exynos: reorganized and updated from insignal

Changes needed on exynos4210 devices:

libcsc -> libseccscapi
libswconverter -> remove

TARGET_HAL_PATH := hardware/samsung/exynos4/hal
TARGET_OMX_PATH := hardware/samsung/exynos/multimedia/openmax
$(call inherit-product, hardware/samsung/exynos4210.mk)

Change-Id: Ic59ef95b85ef37b3f38fb36cf6a364a5414685ee
diff --git a/exynos5/hal/libcamera/Android.mk b/exynos5/hal/libcamera/Android.mk
new file mode 100644
index 0000000..9ab5b2f
--- /dev/null
+++ b/exynos5/hal/libcamera/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# HAL module implemenation stored in
+# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.product.board>.so
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include
+
+LOCAL_SRC_FILES:= \
+	SecCamera.cpp \
+	SecCameraHWInterface.cpp \
+	mediactl.cpp \
+
+LOCAL_SHARED_LIBRARIES:= libutils libcutils libbinder liblog libcamera_client libhardware
+
+LOCAL_CFLAGS += -DGAIA_FW_BETA
+
+ifeq ($(BOARD_USES_HWJPEG),true)
+LOCAL_SHARED_LIBRARIES += libhwjpeg
+LOCAL_CFLAGS += -DSAMSUNG_EXYNOS5250
+endif
+
+LOCAL_MODULE := camera.$(TARGET_DEVICE)
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/exynos5/hal/libcamera/NOTICE b/exynos5/hal/libcamera/NOTICE
new file mode 100644
index 0000000..f921593
--- /dev/null
+++ b/exynos5/hal/libcamera/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (C) 2008 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/exynos5/hal/libcamera/SecCamera.cpp b/exynos5/hal/libcamera/SecCamera.cpp
new file mode 100644
index 0000000..2b434c5
--- /dev/null
+++ b/exynos5/hal/libcamera/SecCamera.cpp
@@ -0,0 +1,3693 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ * Copyright 2010, Samsung Electronics Co. LTD
+ *
+ * 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.
+ */
+
+/*
+************************************
+* Filename: SecCamera.cpp
+* Author:   Sachin P. Kamat
+* Purpose:  This file interacts with the Camera and JPEG drivers.
+*************************************
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SecCamera"
+
+#include <utils/Log.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/poll.h>
+#include "SecCamera.h"
+#include "cutils/properties.h"
+#include <videodev2.h>
+#include "mediactl.h"
+#include "v4l2subdev.h"
+
+using namespace android;
+
+#define CHECK(return_value)                                          \
+    if (return_value < 0) {                                          \
+        LOGE("%s::%d fail. errno: %s, m_camera_id = %d",             \
+             __func__, __LINE__, strerror(errno), m_camera_id);      \
+        return -1;                                                   \
+    }
+
+#define CHECK_PTR(return_value)                                      \
+    if (return_value < 0) {                                          \
+        LOGE("%s::%d fail, errno: %s, m_camera_id = %d",             \
+             __func__,__LINE__, strerror(errno), m_camera_id);       \
+        return NULL;                                                 \
+    }
+
+#define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
+
+namespace android {
+
+static struct timeval time_start;
+static struct timeval time_stop;
+int cam_fd1, cam_fd2;
+
+#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
+unsigned long measure_time_camera(struct timeval *start, struct timeval *stop)
+{
+    unsigned long sec, usec, time;
+
+    sec = stop->tv_sec - start->tv_sec;
+
+    if (stop->tv_usec >= start->tv_usec) {
+        usec = stop->tv_usec - start->tv_usec;
+    } else {
+        usec = stop->tv_usec + 1000000 - start->tv_usec;
+        sec--;
+    }
+
+    time = (sec * 1000000) + usec;
+
+    return time;
+}
+#endif
+
+static int gsc_cap_open(int id)
+{
+    char node[20];
+    int fd;
+
+    id += GSC_VD_NODE_OFFSET;
+    sprintf(node, "%s%d", PFX_NODE_GSC, id);
+    LOGE("(%s): %s%d", __func__, PFX_NODE_GSC, id);
+
+    fd = open(node, O_RDWR, 0);
+    if(fd < 0) {
+        LOGE("ERR(%s): Open gscaler video device failed", __func__);
+        return -1;
+    }
+    LOGE("%s open", node);
+
+    return fd;
+}
+
+static int close_buffers(struct SecBuffer *buffers)
+{
+    int i, j;
+    int ret;
+
+    for (i = 0; i < MAX_BUFFERS; i++) {
+        for(j = 0; j < MAX_PLANES; j++) {
+            if (buffers[i].virt.extP[j]) {
+                buffers[i].virt.extP[j] = NULL;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int get_pixel_depth(unsigned int fmt)
+{
+    int depth = 0;
+
+    switch (fmt) {
+    case V4L2_PIX_FMT_JPEG:
+        depth = 8;
+    break;
+
+    case V4L2_PIX_FMT_NV12:
+    case V4L2_PIX_FMT_NV12T:
+    case V4L2_PIX_FMT_NV21:
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YVU420:
+    case V4L2_PIX_FMT_YVU420M:
+    case V4L2_PIX_FMT_NV12M:
+    case V4L2_PIX_FMT_NV12MT:
+        depth = 12;
+        break;
+
+    case V4L2_PIX_FMT_RGB565:
+    case V4L2_PIX_FMT_RGB565X:
+    case V4L2_PIX_FMT_YUYV:
+    case V4L2_PIX_FMT_YVYU:
+    case V4L2_PIX_FMT_UYVY:
+    case V4L2_PIX_FMT_VYUY:
+    case V4L2_PIX_FMT_NV16:
+    case V4L2_PIX_FMT_NV61:
+    case V4L2_PIX_FMT_YUV422P:
+        depth = 16;
+        break;
+
+    case V4L2_PIX_FMT_RGB32:
+        depth = 32;
+        break;
+
+    default:
+        LOGE("ERR(%s):Get depth failed.", __func__);
+    break;
+    }
+
+    return depth;
+}
+
+static int gsc_cap_poll(struct pollfd *events)
+{
+    int ret;
+
+    /* 10 second delay is because sensor can take a long time
+     * to do auto focus and capture in dark settings
+     */
+    ret = poll(events, 1, 10000);
+    if (ret < 0) {
+        LOGE("ERR(%s):poll error", __func__);
+        return ret;
+    }
+
+    if (ret == 0) {
+        LOGE("ERR(%s):No data in 10 secs..", __func__);
+        return ret;
+    }
+
+    return ret;
+}
+
+static int v4l2_gsc_cap_querycap(int fp)
+{
+    struct v4l2_capability cap;
+
+    if (ioctl(fp, VIDIOC_QUERYCAP, &cap) < 0) {
+        LOGE("ERR(%s):VIDIOC_QUERYCAP failed", __func__);
+        return -1;
+    }
+
+    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) {
+        LOGE("ERR(%s):no capture devices", __func__);
+        return -1;
+    }
+    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
+        LOGE("ERR(%s):no streaming capture devices", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static const __u8* v4l2_gsc_cap_enuminput(int fp, int index)
+{
+    static struct v4l2_input input;
+
+    input.index = index;
+    if (ioctl(fp, VIDIOC_ENUMINPUT, &input) != 0) {
+        LOGE("ERR(%s):No matching index found", __func__);
+        return NULL;
+    }
+    LOGI("Name of input channel[%d] is %s", input.index, input.name);
+
+    return input.name;
+}
+
+static int v4l2_gsc_cap_s_input(int fp, int index)
+{
+    struct v4l2_input input;
+
+    input.index = index;
+
+    if (ioctl(fp, VIDIOC_S_INPUT, &input) < 0) {
+        LOGE("ERR(%s):VIDIOC_S_INPUT failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_g_fmt(int fp)
+{
+    struct v4l2_format v4l2_fmt;
+
+    v4l2_fmt.type = V4L2_BUF_TYPE;
+
+    if(ioctl(fp,  VIDIOC_G_FMT,  &v4l2_fmt) < 0){
+        LOGE("ERR(%s):VIDIOC_G_FMT failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_s_fmt(int fp, int width, int height, unsigned int fmt, enum v4l2_field field, unsigned int num_plane)
+{
+    struct v4l2_format v4l2_fmt;
+    struct v4l2_pix_format pixfmt;
+    unsigned int framesize;
+
+    memset(&v4l2_fmt, 0, sizeof(struct v4l2_format));
+    v4l2_fmt.type = V4L2_BUF_TYPE;
+
+    framesize = (width * height * get_pixel_depth(fmt)) / 8;
+
+    v4l2_fmt.fmt.pix_mp.width = width;
+    v4l2_fmt.fmt.pix_mp.height = height;
+    v4l2_fmt.fmt.pix_mp.pixelformat = fmt;
+    v4l2_fmt.fmt.pix_mp.field = field;
+    if (num_plane == 1) {
+        v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = framesize;
+    } else if (num_plane == 2) {
+        v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width * height, 2048);
+        v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 16) * ALIGN(height/2, 16) * 2;
+    } else if (num_plane == 3) {
+        v4l2_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = ALIGN(width, 16) * ALIGN(height, 16);
+        v4l2_fmt.fmt.pix_mp.plane_fmt[1].sizeimage = ALIGN(width/2, 8) * ALIGN(height/2, 8);
+        v4l2_fmt.fmt.pix_mp.plane_fmt[2].sizeimage = ALIGN(width/2, 8) * ALIGN(height/2, 8);
+    } else {
+        LOGE("ERR(%s): Invalid plane number", __func__);
+        return -1;
+    }
+    v4l2_fmt.fmt.pix_mp.num_planes = num_plane;
+
+    /* Set up for capture */
+    if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+        LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_s_fmt_cap(int fp, int width, int height, unsigned int fmt)
+{
+    struct v4l2_format v4l2_fmt;
+    struct v4l2_pix_format pixfmt;
+
+    memset(&pixfmt, 0, sizeof(pixfmt));
+
+    v4l2_fmt.type = V4L2_BUF_TYPE;
+
+    pixfmt.width = width;
+    pixfmt.height = height;
+    pixfmt.pixelformat = fmt;
+    if (fmt == V4L2_PIX_FMT_JPEG)
+        pixfmt.colorspace = V4L2_COLORSPACE_JPEG;
+
+    v4l2_fmt.fmt.pix = pixfmt;
+
+    /* Set up for capture */
+    if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+        LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int v4l2_gsc_cap_s_fmt_is(int fp, int width, int height, unsigned int fmt, enum v4l2_field field)
+{
+    struct v4l2_format v4l2_fmt;
+    struct v4l2_pix_format pixfmt;
+
+    memset(&pixfmt, 0, sizeof(pixfmt));
+
+    v4l2_fmt.type = V4L2_BUF_TYPE_PRIVATE;
+
+    pixfmt.width = width;
+    pixfmt.height = height;
+    pixfmt.pixelformat = fmt;
+    pixfmt.field = field;
+
+    v4l2_fmt.fmt.pix = pixfmt;
+
+    /* Set up for capture */
+    if (ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+        LOGE("ERR(%s):VIDIOC_S_FMT failed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_enum_fmt(int fp, unsigned int fmt)
+{
+    struct v4l2_fmtdesc fmtdesc;
+    int found = 0;
+
+    fmtdesc.type = V4L2_BUF_TYPE;
+    fmtdesc.index = 0;
+
+    while (ioctl(fp, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
+        if (fmtdesc.pixelformat == fmt) {
+            LOGV("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description);
+            found = 1;
+            break;
+        }
+
+        fmtdesc.index++;
+    }
+
+    if (!found) {
+        LOGE("unsupported pixel format");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_reqbufs(int fp, enum v4l2_buf_type type, int nr_bufs)
+{
+    struct v4l2_requestbuffers req;
+
+    req.count = nr_bufs;
+    req.type = type;
+    req.memory = V4L2_MEMORY_TYPE;
+
+    if (ioctl(fp, VIDIOC_REQBUFS, &req) < 0) {
+        LOGE("ERR(%s):VIDIOC_REQBUFS failed", __func__);
+        return -1;
+    }
+
+    if (req.count > MAX_BUFFERS ) {
+        LOGE("ERR(%s):Insufficient buffer memory on", __func__);
+        return -1;
+    }
+
+    return req.count;
+}
+
+static int v4l2_gsc_cap_querybuf(int fp, struct SecBuffer *buffers, enum v4l2_buf_type type, int nr_frames, int num_plane)
+{
+    struct v4l2_buffer v4l2_buf;
+    struct v4l2_plane planes[VIDEO_MAX_PLANES];
+    int i, plane_index;
+
+    for (i = 0; i < nr_frames; i++) {
+        v4l2_buf.type = type;
+        v4l2_buf.memory = V4L2_MEMORY_TYPE;
+        v4l2_buf.index = i;
+        v4l2_buf.m.planes = planes;
+        v4l2_buf.length = num_plane;  // this is for multi-planar
+        LOGV("QUERYBUF(index=%d)", i);
+        LOGV("Memory plane is %d", v4l2_buf.length);
+
+        if (ioctl(fp, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
+            LOGE("ERR(%s):VIDIOC_QUERYBUF failed", __func__);
+            return -1;
+        }
+
+        for (plane_index = 0; plane_index < num_plane; plane_index++) {
+            LOGV("Offset : 0x%x", v4l2_buf.m.planes[plane_index].m.mem_offset);
+            LOGV("Plane Length : 0x%x", v4l2_buf.m.planes[plane_index].length);
+
+            buffers[i].phys.extP[plane_index] = (unsigned int)v4l2_buf.m.planes[plane_index].cookie;
+
+            buffers[i].size.extS[plane_index] = v4l2_buf.m.planes[plane_index].length;
+            LOGV("Length[%d] : 0x%x", i, buffers[i].size.extS[plane_index]);
+            if ((buffers[i].virt.extP[plane_index] = (char *)mmap(0, v4l2_buf.m.planes[plane_index].length,
+                    PROT_READ | PROT_WRITE, MAP_SHARED, fp, v4l2_buf.m.planes[plane_index].m.mem_offset)) < 0) {
+                LOGE("mmap failed");
+                return -1;
+            }
+            LOGV("vaddr[%d][%d] : 0x%x", i, plane_index, (__u32) buffers[i].virt.extP[plane_index]);
+        }
+    }
+    return 0;
+}
+
+static int v4l2_gsc_cap_streamon(int fp)
+{
+    enum v4l2_buf_type type = V4L2_BUF_TYPE;
+    int ret;
+
+    LOGV("%s : On streaming I/O", __func__);
+    ret = ioctl(fp, VIDIOC_STREAMON, &type);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_STREAMON failed", __func__);
+        return ret;
+    }
+
+    return ret;
+}
+
+static int v4l2_gsc_cap_streamoff(int fp)
+{
+    enum v4l2_buf_type type = V4L2_BUF_TYPE;
+    int ret;
+
+    LOGV("%s :", __func__);
+    ret = ioctl(fp, VIDIOC_STREAMOFF, &type);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_STREAMOFF failed", __func__);
+        return ret;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_qbuf(int fp, int width, int height, struct SecBuffer *vaddr, int index, int num_plane)
+{
+    struct v4l2_buffer v4l2_buf;
+    int ret;
+
+    struct v4l2_plane planes[VIDEO_MAX_PLANES];
+
+    v4l2_buf.m.planes = planes;
+    v4l2_buf.length = num_plane;
+
+    v4l2_buf.type = V4L2_BUF_TYPE;
+    v4l2_buf.memory = V4L2_MEMORY_TYPE;
+    v4l2_buf.index = index;
+
+    if(fp == cam_fd1) {
+        if (num_plane == 1) {
+            v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0];
+            v4l2_buf.m.planes[0].length = width * height * 2;
+        } else if (num_plane == 2) {
+            v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0];
+            v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16);
+            v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1];
+            v4l2_buf.m.planes[1].length = ALIGN(width/2, 16) * ALIGN(height/2, 16);
+        } else if (num_plane == 3) {
+            v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0];
+            v4l2_buf.m.planes[0].length = ALIGN(width, 16) * ALIGN(height, 16);
+            v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1];
+            v4l2_buf.m.planes[1].length = ALIGN(width/2, 8) * ALIGN(height/2, 8);
+            v4l2_buf.m.planes[2].m.userptr = (long unsigned int)vaddr[index].virt.extP[2];
+            v4l2_buf.m.planes[2].length = ALIGN(width/2, 8) * ALIGN(height/2, 8);
+        } else {
+            LOGE("ERR(%s): Invalid plane number", __func__);
+            return -1;
+        }
+    }
+    else if(fp == cam_fd2) {
+        v4l2_buf.m.planes[0].m.userptr = (long unsigned int)vaddr[index].virt.extP[0];
+        v4l2_buf.m.planes[0].length = ALIGN(ALIGN(width, 16) * ALIGN(height, 16), 2048);
+        v4l2_buf.m.planes[1].m.userptr = (long unsigned int)vaddr[index].virt.extP[1];
+        v4l2_buf.m.planes[1].length = ALIGN(ALIGN(width, 16) * ALIGN(height >> 1, 8), 2048);
+    }
+    else {
+        return -1;
+    }
+
+    ret = ioctl(fp, VIDIOC_QBUF, &v4l2_buf);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_QBUF failed", __func__);
+        return ret;
+    }
+
+    return 0;
+}
+
+static int v4l2_gsc_cap_dqbuf(int fp, int num_plane)
+{
+    struct v4l2_buffer v4l2_buf;
+    int ret;
+
+    struct v4l2_plane planes[VIDEO_MAX_PLANES];
+
+    v4l2_buf.m.planes = planes;
+    v4l2_buf.length = num_plane;
+
+    v4l2_buf.type = V4L2_BUF_TYPE;
+    v4l2_buf.memory = V4L2_MEMORY_TYPE;
+
+    ret = ioctl(fp, VIDIOC_DQBUF, &v4l2_buf);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_DQBUF failed, dropped frame", __func__);
+        return ret;
+    }
+
+    return v4l2_buf.index;
+}
+
+static int v4l2_gsc_cap_g_ctrl(int fp, unsigned int id)
+{
+    struct v4l2_control ctrl;
+    int ret;
+
+    ctrl.id = id;
+
+    ret = ioctl(fp, VIDIOC_G_CTRL, &ctrl);
+    if (ret < 0) {
+        LOGE("ERR(%s): VIDIOC_G_CTRL(id = 0x%x (%d)) failed, ret = %d",
+             __func__, id, id-V4L2_CID_PRIVATE_BASE, ret);
+        return ret;
+    }
+
+    return ctrl.value;
+}
+
+static int v4l2_gsc_cap_s_ctrl(int fp, unsigned int id, unsigned int value)
+{
+    struct v4l2_control ctrl;
+    int ret;
+
+    ctrl.id = id;
+    ctrl.value = value;
+
+    ret = ioctl(fp, VIDIOC_S_CTRL, &ctrl);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_S_CTRL(id = %#x (%d), value = %d) failed ret = %d",
+             __func__, id, id-V4L2_CID_PRIVATE_BASE, value, ret);
+
+        return ret;
+    }
+
+    return ctrl.value;
+}
+
+static int v4l2_gsc_cap_s_ext_ctrl(int fp, unsigned int id, void *value)
+{
+    struct v4l2_ext_controls ctrls;
+    struct v4l2_ext_control ctrl;
+    int ret;
+
+    ctrl.id = id;
+
+    ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
+    ctrls.count = 1;
+    ctrls.controls = &ctrl;
+
+    ret = ioctl(fp, VIDIOC_S_EXT_CTRLS, &ctrls);
+    if (ret < 0)
+        LOGE("ERR(%s):VIDIOC_S_EXT_CTRLS failed", __func__);
+
+    return ret;
+}
+
+static int v4l2_gsc_cap_g_parm(int fp, struct v4l2_streamparm *streamparm)
+{
+    int ret;
+
+    streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    ret = ioctl(fp, VIDIOC_G_PARM, streamparm);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_G_PARM failed", __func__);
+        return ret;
+    }
+
+    LOGV("%s : timeperframe: numerator %d, denominator %d", __func__,
+            streamparm->parm.capture.timeperframe.numerator,
+            streamparm->parm.capture.timeperframe.denominator);
+
+    return ret;
+}
+
+static int v4l2_gsc_cap_s_parm(int fp, struct v4l2_streamparm *streamparm)
+{
+    int ret;
+
+    streamparm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    ret = ioctl(fp, VIDIOC_S_PARM, streamparm);
+    if (ret < 0) {
+        LOGE("ERR(%s):VIDIOC_S_PARM failed", __func__);
+        return ret;
+    }
+
+    return ret;
+}
+
+static int v4l2_subdev_open(struct media_entity *entity)
+{
+    int fd;
+
+    fd = open(entity->devname,  O_RDWR, 0);
+    if(fd < 0){
+        LOGE("ERR(%s): Open failed.", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int v4l2_subdev_get_fmt(int fd, struct v4l2_subdev_format *fmt)
+{
+    if(ioctl(fd, VIDIOC_SUBDEV_G_FMT, fmt)) {
+        LOGE("ERR(%s):  subdev get foramt failed.", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+SecCamera::SecCamera() :
+            m_flagCreate(0),
+            m_camera_id(CAMERA_ID_BACK),
+            m_gsc_vd_fd(-1),
+            m_cam_fd2(-1),
+            m_jpeg_fd(-1),
+            m_flag_record_start(0),
+            m_preview_v4lformat(V4L2_PIX_FMT_YVU420M),
+            m_preview_width      (0),
+            m_preview_height     (0),
+            m_preview_max_width  (MAX_BACK_CAMERA_PREVIEW_WIDTH),
+            m_preview_max_height (MAX_BACK_CAMERA_PREVIEW_HEIGHT),
+            m_snapshot_v4lformat(-1),
+            m_snapshot_width      (0),
+            m_snapshot_height     (0),
+            m_snapshot_max_width  (MAX_BACK_CAMERA_SNAPSHOT_WIDTH),
+            m_snapshot_max_height (MAX_BACK_CAMERA_SNAPSHOT_HEIGHT),
+            m_picture_vaddr(NULL),
+            m_recording_en        (0),
+            m_recording_width     (0),
+            m_recording_height    (0),
+            m_angle(-1),
+            m_anti_banding(-1),
+            m_wdr(-1),
+            m_anti_shake(-1),
+            m_zoom_level(-1),
+            m_object_tracking(-1),
+            m_smart_auto(-1),
+            m_beauty_shot(-1),
+            m_vintage_mode(-1),
+            m_face_detect(-1),
+            m_object_tracking_start_stop(-1),
+            m_gps_latitude(-1),
+            m_gps_longitude(-1),
+            m_gps_altitude(-1),
+            m_gps_timestamp(-1),
+            m_sensor_mode(-1),
+            m_shot_mode(-1),
+            m_exif_orientation(-1),
+            m_chk_dataline(-1),
+            m_video_gamma(-1),
+            m_slow_ae(-1),
+            m_camera_af_flag(-1),
+            m_flag_camera_start(0),
+            m_jpeg_thumbnail_width (0),
+            m_jpeg_thumbnail_height(0),
+            m_jpeg_thumbnail_quality(100),
+            m_jpeg_quality(100),
+            m_touch_af_start_stop(-1),
+            m_postview_offset(0)
+#ifdef ENABLE_ESD_PREVIEW_CHECK
+            ,
+            m_esd_check_count(0)
+#endif // ENABLE_ESD_PREVIEW_CHECK
+{
+    memset(&m_streamparm, 0, sizeof(m_streamparm));
+    m_params = (struct sec_cam_parm*)&m_streamparm.parm.raw_data;
+    struct v4l2_captureparm capture;
+    m_params->capture.timeperframe.numerator = 1;
+    m_params->capture.timeperframe.denominator = 0;
+    m_params->contrast = -1;
+    m_params->effects = -1;
+    m_params->brightness = -1;
+    m_params->exposure = -1;
+    m_params->flash_mode = -1;
+    m_params->focus_mode = -1;
+    m_params->iso = -1;
+    m_params->metering = -1;
+    m_params->saturation = -1;
+    m_params->scene_mode = -1;
+    m_params->sharpness = -1;
+    m_params->white_balance = -1;
+
+    memset(&mExifInfo, 0, sizeof(mExifInfo));
+
+    memset(&m_events_c, 0, sizeof(m_events_c));
+    memset(&m_events_c2, 0, sizeof(m_events_c2));
+}
+
+SecCamera::~SecCamera()
+{
+    LOGV("%s :", __func__);
+    DestroyCamera();
+}
+
+bool SecCamera::CreateCamera(int index)
+{
+    LOGV("%s:", __func__);
+    char node[30];
+    int i;
+    int ret = 0;
+
+    LOGV("%s: m_flagCreate : %d", __func__, m_flagCreate);
+    if (!m_flagCreate) {
+        /* Arun C
+         * Reset the lense position only during camera starts; don't do
+         * reset between shot to shot
+         */
+        m_flagCreate = 1;
+        m_camera_af_flag = -1;
+
+        /* media device open */
+        LOGV("%s: m_flagCreate : %d", __func__, m_flagCreate);
+
+        media = media_open();
+        if (media == NULL) {
+            LOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno));
+        return -1;
+    }
+
+#ifndef GAIA_FW_BETA
+        //////////////////
+        /* GET ENTITIES */
+        //////////////////
+        /* camera subdev */
+        strcpy(node, M5MOLS_ENTITY_NAME);
+    LOGV("%s : node : %s", __func__, node);
+    camera_sd_entity = media_get_entity_by_name(media, node, strlen(node));
+    LOGV("%s : camera_sd_entity : 0x%p", __func__, camera_sd_entity);
+
+        /* mipi-csis subdev */
+        sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_MIPI_CSIS, MIPI_NUM);
+    LOGV("%s : node : %s", __func__, node);
+    mipi_sd_entity = media_get_entity_by_name(media, node, strlen(node));
+    LOGV("%s : mipi_sd_entity : 0x%p", __func__, mipi_sd_entity);
+
+        /* fimc-lite subdev */
+        sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_FLITE, FLITE_NUM);
+    LOGV("%s : node : %s", __func__, node);
+    flite_sd_entity = media_get_entity_by_name(media, node, strlen(node));
+    LOGV("%s : flite_sd_entity : 0x%p", __func__, flite_sd_entity);
+
+        /* gscaler-capture subdev */
+        sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_GSC_CAP, GSC_NUM);
+    LOGV("%s : node : %s", __func__, node);
+    gsc_cap_sd_entity = media_get_entity_by_name(media, node, strlen(node));
+    LOGV("%s : gsc_cap_sd_entity : 0x%p", __func__, gsc_cap_sd_entity);
+
+        /* gscaler-capture subdev */
+        sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_GSC_CAP, GSC_NUM);
+    LOGV("%s : node : %s", __func__, node);
+    gsc_cap_vd_entity = media_get_entity_by_name(media, node, strlen(node));
+    LOGV("%s : gsc_cap_vd_entity : 0x%p", __func__, gsc_cap_vd_entity);
+
+    LOGV("camera_sd : numlink : %d", camera_sd_entity->num_links);
+    LOGV("mipi_sd : numlink : %d", mipi_sd_entity->num_links);
+    LOGV("flite_sd : numlink : %d", flite_sd_entity->num_links);
+    LOGV("gsc_cap_sd : numlink : %d", gsc_cap_sd_entity->num_links);
+    LOGV("gsc_cap_vd : numlink : %d", gsc_cap_vd_entity->num_links);
+
+        //////////////////
+        /* SETUP LINKS */
+        //////////////////
+    /*camera sensor to mipi-csis */
+    links = camera_sd_entity->links;
+    if (links == NULL ||
+        links->source->entity != camera_sd_entity ||
+        links->sink->entity != mipi_sd_entity) {
+        LOGE("ERR(%s): Cannot make link camera sensor to mipi-csis", __func__);
+        return -1;
+    }
+        if (media_setup_link(media,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+        LOGE("ERR(%s): Cannot make setup camera sensor to mipi-csis", __func__);
+        return -1;
+    }
+        LOGV("[LINK SUCCESS] camera seneor to mipi-csis");
+
+        /*mipi-csis to fimc-lite*/
+    for(i = 0; i < mipi_sd_entity->num_links; i++) {
+            links = &mipi_sd_entity->links[i];
+                LOGV("(%s), i=%d: links->source->entity : %p, mipi_sd_entity : %p", __func__, i,
+                                                  links->source->entity, mipi_sd_entity);
+                LOGV("(%s), i=%d: links->sink->entity : %p, flite_sd_entity : %p", __func__, i,
+                                                  links->sink->entity, flite_sd_entity);
+            if (links == NULL ||
+                links->source->entity != mipi_sd_entity ||
+                links->sink->entity != flite_sd_entity) {
+            continue;
+            } else if (media_setup_link(media,  links->source,  links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+                LOGE("ERR(%s): Cannot make setup mipi-csis to fimc-lite", __func__);
+                return -1;
+            }
+        }
+        LOGV("[LINK SUCCESS] mipi-csis to fimc-lite");
+
+        /*fimc-lite to gscaler capture device*/
+    for(i = 0; i < gsc_cap_sd_entity->num_links; i++) {
+            links = &gsc_cap_sd_entity->links[i];
+                LOGV("(%s), i=%d: links->source->entity : %p, flite_sd_entity : %p", __func__, i,
+                                                  links->source->entity, flite_sd_entity);
+                LOGV("(%s), i=%d: links->sink->entity : %p, gsc_cap_sd_entity : %p", __func__, i,
+                                                  links->sink->entity, gsc_cap_sd_entity);
+            if (links == NULL ||
+                links->source->entity != flite_sd_entity ||
+                links->sink->entity != gsc_cap_sd_entity) {
+            continue;
+            } else if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+                LOGE("ERR(%s): Cannot make setup fimc-lite to gscaler capture device", __func__);
+                return -1;
+            }
+        }
+        LOGV("[LINK SUCCESS] fimc-lite to gscaler capture device");
+
+        /*gscaler capture device to gscaler video device*/
+    for(i = 0; i < gsc_cap_vd_entity->num_links; i++) {
+            links = &gsc_cap_vd_entity->links[i];
+                LOGV("(%s), i=%d: links->source->entity : %p, gsc_cap_sd_entity : %p", __func__, i,
+                                                  links->source->entity, gsc_cap_sd_entity);
+                LOGV("(%s), i=%d: links->sink->entity : %p, gsc_cap_vd_entity : %p", __func__, i,
+                                                  links->sink->entity, gsc_cap_vd_entity);
+            if (links == NULL ||
+                links->source->entity != gsc_cap_sd_entity ||
+                links->sink->entity != gsc_cap_vd_entity) {
+            continue;
+            } else if (media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+                LOGE("ERR(%s): Cannot make setup gscaler capture device to gscaler video device", __func__);
+                return -1;
+            }
+        }
+        LOGV("[LINK SUCCESS] gscaler capture device to gscaler video device");
+#else
+//////////////////////////////
+//  internal IS
+//////////////////////////////
+        //////////////////
+        /* GET ENTITIES */
+        //////////////////
+    /* ISP sensor subdev */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_SENSOR_ENTITY_NAME);
+    isp_sensor_entity = media_get_entity_by_name(media, node, strlen(node));
+
+    /* ISP front subdev */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_FRONT_ENTITY_NAME);
+    isp_front_entity = media_get_entity_by_name(media, node, strlen(node));
+
+    /* ISP back subdev */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_BACK_ENTITY_NAME);
+    isp_back_entity = media_get_entity_by_name(media, node, strlen(node));
+
+
+    /* ISP ScalerC video node */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_VIDEO_SCALERC_NAME);
+    isp_scalerc_entity = media_get_entity_by_name(media, node, strlen(node));
+
+    /* ISP ScalerP video node */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_VIDEO_SCALERP_NAME);
+    isp_scalerp_entity = media_get_entity_by_name(media, node, strlen(node));
+
+    /* ISP 3DNR video node */
+    memset(&node, 0x00, sizeof(node));
+    strcpy(node, ISP_VIDEO_3DNR_NAME);
+    isp_3dnr_entity = media_get_entity_by_name(media, node, strlen(node));
+
+    LOGV("isp_sensor_entity : numlink : %d", isp_sensor_entity->num_links);
+    LOGV("isp_front_entity : numlink : %d", isp_front_entity->num_links);
+    LOGV("isp_back_entity : numlink : %d", isp_back_entity->num_links);
+    LOGV("isp_scalerc_entity : numlink : %d", isp_scalerc_entity->num_links);
+    LOGV("isp_scalerp_entity : numlink : %d", isp_scalerp_entity->num_links);
+    LOGV("isp_3dnr_entity : numlink : %d", isp_3dnr_entity->num_links);
+
+        //////////////////
+        /* SETUP LINKS */
+        //////////////////
+    /* SENSOR TO FRONT */
+    links = isp_sensor_entity->links;
+    if (links == NULL ||
+            links->source->entity != isp_sensor_entity ||
+            links->sink->entity != isp_front_entity) {
+            LOGE("[ERR] Can not make link isp_sensor to isp_front\n");
+        return -1;
+    }
+    if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+        LOGE("[ERR] Can not make setup isp_sensor to isp_front\n");
+        return -1;
+    }
+    LOGV("[LINK SUCCESS] Sensor to front");
+
+    /* FRONT TO BACK */
+    for (i = 0; i < isp_front_entity->num_links; i++){
+        links = &isp_front_entity->links[i];
+        if (links == NULL ||
+            links->source->entity != isp_front_entity ||
+            links->sink->entity != isp_back_entity) {
+                LOGV("(%s), i=%d: links->source->entity : %p, isp_front_entity : %p", __func__, i,
+                                                  links->source->entity, isp_front_entity);
+                LOGV("(%s), i=%d: links->sink->entity : %p, isp_back_entity : %p", __func__, i,
+                                                  links->sink->entity, isp_back_entity);
+                continue;
+        } else if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+                LOGE("[ERR] Can not make setup isp_front to isp_back\n");
+            return -1;
+        }
+    }
+    LOGV("[LINK SUCCESS] front to back");
+
+    /* BACK TO ScalerP Video*/
+    for (i = 0; i < isp_back_entity->num_links; i++){
+        links = &isp_back_entity->links[i];
+        if (links == NULL ||
+            links->source->entity != isp_back_entity ||
+            links->sink->entity != isp_scalerp_entity) {
+                LOGV("(%s), i=%d: links->source->entity : %p, isp_front_entity : %p", __func__, i,
+                                                  links->source->entity, isp_front_entity);
+                LOGV("(%s), i=%d: links->sink->entity : %p, isp_back_entity : %p", __func__, i,
+                                                  links->sink->entity, isp_back_entity);
+                continue;
+        }
+                if(media_setup_link(media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
+            LOGE("[ERR] Can not make setup isp_back to scalerP\n");
+                    return -1;
+        }
+    }
+    LOGV("[LINK SUCCESS] back to scalerP");
+#endif
+
+    m_gsc_vd_fd = gsc_cap_open(0);
+    cam_fd1 = m_gsc_vd_fd;
+        if (m_gsc_vd_fd < 0) {
+            LOGE("ERR(%s):Cannot open %s (error : %s)", __func__, PFX_NODE_GSC, strerror(errno));
+            return -1;
+        }
+
+#ifndef GAIA_FW_BETA
+        if (!v4l2_gsc_cap_enuminput(m_gsc_vd_fd, index)) {
+            LOGE("m_gsc_vd_fd(%d) v4l2_gsc_cap_enuminput fail", m_gsc_vd_fd);
+            return -1;
+        }
+
+        ret = v4l2_gsc_cap_s_input(m_gsc_vd_fd, index);
+        CHECK(ret);
+#endif
+
+        m_camera_id = index;
+
+        switch (m_camera_id) {
+        case CAMERA_ID_FRONT:
+            m_preview_max_width   = MAX_FRONT_CAMERA_PREVIEW_WIDTH;
+            m_preview_max_height  = MAX_FRONT_CAMERA_PREVIEW_HEIGHT;
+            m_snapshot_max_width  = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH;
+            m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT;
+            break;
+
+        case CAMERA_ID_BACK:
+            m_preview_max_width   = MAX_BACK_CAMERA_PREVIEW_WIDTH;
+            m_preview_max_height  = MAX_BACK_CAMERA_PREVIEW_HEIGHT;
+            m_snapshot_max_width  = MAX_BACK_CAMERA_SNAPSHOT_WIDTH;
+            m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT;
+            break;
+        }
+
+        //setExifFixedAttribute();
+    }
+    return 0;
+}
+
+void SecCamera::resetCamera()
+{
+    LOGV("%s :", __func__);
+    DestroyCamera();
+    CreateCamera(m_camera_id);
+}
+
+bool SecCamera::DestroyCamera()
+{
+    LOGV("%s :", __func__);
+
+    if (m_flagCreate) {
+
+        stopRecord();
+
+        /* close m_gsc_vd_fd after stopRecord() because stopRecord()
+         * uses m_gsc_vd_fd to change frame rate
+         */
+        LOGI("DestroyCamera: m_gsc_vd_fd(%d)", m_gsc_vd_fd);
+        if (m_gsc_vd_fd > -1) {
+            close(m_gsc_vd_fd);
+            m_gsc_vd_fd = -1;
+        }
+
+        LOGI("DestroyCamera: m_cam_fd2(%d)", m_cam_fd2);
+        if (m_cam_fd2 > -1) {
+            close(m_cam_fd2);
+            m_cam_fd2 = -1;
+        }
+
+        m_flagCreate = 0;
+    } else
+        LOGI("%s : already deinitialized", __func__);
+
+    return 0;
+}
+
+int SecCamera::getCameraFd(void)
+{
+    return m_gsc_vd_fd;
+}
+
+unsigned char* SecCamera::getPictureVaddr(void)
+{
+    return m_picture_vaddr;
+}
+
+int SecCamera::startPreview(void)
+{
+    v4l2_streamparm streamparm;
+    struct sec_cam_parm *parms;
+    int    ret;
+
+    parms = (struct sec_cam_parm*)&streamparm.parm.raw_data;
+    LOGV("%s :", __func__);
+
+    // check preview is aleady started.
+    if (m_flag_camera_start > 0) {
+        LOGE("ERR(%s):Preview was already started", __func__);
+        return 0;
+    }
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    memset(&m_events_c, 0, sizeof(m_events_c));
+    m_events_c.fd = m_gsc_vd_fd;
+    m_events_c.events = POLLIN | POLLERR;
+
+#ifndef GAIA_FW_BETA
+    /* enum_fmt, s_fmt sample */
+    ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd, m_preview_v4lformat);
+    CHECK(ret);
+
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+    LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName());
+
+    if (Internal_is) {
+        if (!m_recording_en)
+            v4l2_gsc_cap_s_fmt_is(m_gsc_vd_fd, m_preview_width, m_preview_height,
+                    m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL);
+        else
+            v4l2_gsc_cap_s_fmt_is(m_gsc_vd_fd, m_recording_width, m_recording_height,
+                    m_preview_v4lformat, (enum v4l2_field) IS_MODE_PREVIEW_STILL);
+
+    }
+
+    ret = v4l2_gsc_cap_s_fmt(m_gsc_vd_fd, m_preview_width, m_preview_height, m_preview_v4lformat, V4L2_FIELD_ANY, PREVIEW_NUM_PLANE);
+    CHECK(ret);
+
+    if (Internal_is) {
+        if (!m_recording_en)
+            ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL);
+        else
+            ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_S_SCENARIO_MODE, IS_MODE_PREVIEW_STILL);
+    }
+    CHECK(ret);
+
+    ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CACHEABLE, 1);
+    CHECK(ret);
+#endif
+
+    ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, MAX_BUFFERS);
+    CHECK(ret);
+
+    LOGV("%s : m_preview_width: %d m_preview_height: %d m_angle: %d",
+            __func__, m_preview_width, m_preview_height, m_angle);
+
+    LOGV("m_camera_id : %d", m_camera_id);
+
+    /* start with all buffers in queue */
+    for (int i = 0; i < MAX_BUFFERS; i++) {
+        ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_preview_width, m_preview_height, m_buffers_preview, i, PREVIEW_NUM_PLANE);
+        CHECK(ret);
+    }
+
+    ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd);
+    CHECK(ret);
+
+    m_flag_camera_start = 1;
+/* TO DO : Frame Rate set is will be availeable.
+    if (setFrameRate(m_params->capture.timeperframe.denominator) < 0)
+        LOGE("ERR(%s):Fail on setFrameRate(%d)",
+            __func__, m_params->capture.timeperframe.denominator);
+*/
+    LOGV("%s: got the first frame of the preview", __func__);
+
+    return 0;
+}
+
+int SecCamera::stopPreview(void)
+{
+    int ret;
+
+    LOGV("%s :", __func__);
+
+    if (m_flag_camera_start == 0) {
+        LOGW("%s: doing nothing because m_flag_camera_start is zero", __func__);
+        return 0;
+    }
+
+    if (m_params->flash_mode == FLASH_MODE_TORCH)
+        setFlashMode(FLASH_MODE_OFF);
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    ret = v4l2_gsc_cap_streamoff(m_gsc_vd_fd);
+    CHECK(ret);
+
+    close_buffers(m_buffers_preview);
+
+    v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, 0);
+
+    m_flag_camera_start = 0;
+
+    return ret;
+}
+
+//Recording
+int SecCamera::startRecord(void)
+{
+    int ret, i;
+
+    LOGV("%s :", __func__);
+
+    // aleady started
+    if (m_flag_record_start > 0) {
+        LOGE("ERR(%s):Preview was already started", __func__);
+        return 0;
+    }
+
+    if (m_cam_fd2 <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    /* enum_fmt, s_fmt sample */
+    ret = v4l2_gsc_cap_enum_fmt(m_cam_fd2, RECORD_PIX_FMT);
+    CHECK(ret);
+
+    LOGI("%s: m_recording_width = %d, m_recording_height = %d",
+         __func__, m_recording_width, m_recording_height);
+
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+    LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName());
+
+//    if (Internal_is)
+//        v4l2_gsc_cap_s_fmt_is(m_cam_fd2, m_recording_width, m_recording_height, RECORD_PIX_FMT, (enum v4l2_field) IS_MODE_CAPTURE_VIDEO);
+
+    ret = v4l2_gsc_cap_s_fmt(m_cam_fd2, m_recording_width,
+                          m_recording_height, RECORD_PIX_FMT, V4L2_FIELD_ANY, RECORD_NUM_PLANE);
+    CHECK(ret);
+
+    ret = v4l2_gsc_cap_reqbufs(m_cam_fd2, V4L2_BUF_TYPE, MAX_BUFFERS);
+    CHECK(ret);
+
+    /* start with all buffers in queue */
+    for (i = 0; i < MAX_BUFFERS; i++) {
+        ret = v4l2_gsc_cap_qbuf(m_cam_fd2, m_recording_width, m_recording_height, m_buffers_record, i, RECORD_NUM_PLANE);
+        CHECK(ret);
+    }
+
+    // Get and throw away the first frame since it is often garbled.
+    memset(&m_events_c2, 0, sizeof(m_events_c2));
+    m_events_c2.fd = m_cam_fd2;
+    m_events_c2.events = POLLIN | POLLERR;
+
+    ret = v4l2_gsc_cap_streamon(m_cam_fd2);
+    CHECK(ret);
+
+    m_flag_record_start = 1;
+
+    return 0;
+}
+
+int SecCamera::stopRecord(void)
+{
+    int ret;
+
+    LOGV("%s :", __func__);
+
+    if (m_flag_record_start == 0) {
+        LOGW("%s: doing nothing because m_flag_record_start is zero", __func__);
+        return 0;
+    }
+
+    if (m_cam_fd2 <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    m_flag_record_start = 0;
+
+    ret = v4l2_gsc_cap_streamoff(m_cam_fd2);
+    CHECK(ret);
+
+    close_buffers(m_buffers_record);
+
+    v4l2_gsc_cap_reqbufs(m_cam_fd2, V4L2_BUF_TYPE, 0);
+
+    return 0;
+}
+
+int SecCamera::getRecordAddr(int index, SecBuffer *buffer)
+{
+    buffer->phys.extP[0] = (unsigned int)m_buffers_record[index].phys.extP[0];
+    buffer->phys.extP[1] = (unsigned int)(m_buffers_record[index].phys.extP[0] + (m_recording_width * m_recording_height));
+    return 0;
+}
+
+int SecCamera::getPreviewAddr(int index, SecBuffer *buffer)
+{
+    buffer->phys.extP[0] = (unsigned int)m_buffers_preview[index].phys.extP[0];
+    buffer->phys.extP[1] = (unsigned int)m_buffers_preview[index].phys.extP[1];
+    buffer->virt.extP[0] = m_buffers_preview[index].virt.extP[0];
+    return 0;
+}
+
+void SecCamera::setUserBufferAddr(void *ptr, int index, int mode)
+{
+    if (mode == PREVIEW_MODE) {
+        m_buffers_preview[index].virt.extP[0] = (char *)((unsigned int *)ptr)[0];
+        m_buffers_preview[index].virt.extP[1] = (char *)((unsigned int *)ptr)[1];
+        m_buffers_preview[index].virt.extP[2] = (char *)((unsigned int *)ptr)[2];
+    } else if (mode == RECORD_MODE) {
+        m_buffers_record[index].virt.extP[0] = (char *)ptr;
+        m_buffers_record[index].virt.extP[1] = (char *)ptr + ((ALIGN(m_recording_width, 16) * ALIGN(m_recording_height, 16)));
+    } else
+        LOGE("%s: Invalid fd!!!", __func__);
+}
+
+int SecCamera::getPreview()
+{
+    int index;
+    int ret;
+
+    LOGV("%s: ", __func__);
+    if (m_flag_camera_start == 0 || gsc_cap_poll(&m_events_c) == 0) {
+        LOGE("ERR(%s):Start Camera Device Reset", __func__);
+        /*
+         * When there is no data for more than 1 second from the camera we inform
+         * the FIMC driver by calling v4l2_gsc_cap_s_input() with a special value = 1000
+         * FIMC driver identify that there is something wrong with the camera
+         * and it restarts the sensor.
+         */
+        stopPreview();
+        /* Reset Only Camera Device */
+        ret = v4l2_gsc_cap_querycap(m_gsc_vd_fd);
+        CHECK(ret);
+#ifndef GAIA_FW_BETA
+        if (v4l2_gsc_cap_enuminput(m_gsc_vd_fd, m_camera_id))
+            return -1;
+        ret = v4l2_gsc_cap_s_input(m_gsc_vd_fd, 1000);
+        CHECK(ret);
+#endif
+        m_preview_state = 0;
+        return -1;
+        ret = startPreview();
+        if (ret < 0) {
+            LOGE("ERR(%s): startPreview() return %d", __func__, ret);
+            return 0;
+        }
+    }
+
+    index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, PREVIEW_NUM_PLANE);
+    if (!(0 <= index && index < MAX_BUFFERS)) {
+        LOGE("ERR(%s):wrong index = %d", __func__, index);
+        return -1;
+    }
+
+    return index;
+}
+
+int SecCamera::setPreviewFrame(int index)
+{
+    int ret;
+    ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_preview_width, m_preview_height, m_buffers_preview, index, PREVIEW_NUM_PLANE);
+    CHECK(ret);
+
+    return ret;
+}
+
+int SecCamera::getRecordFrame()
+{
+    if (m_flag_record_start == 0) {
+        LOGE("%s: m_flag_record_start is 0", __func__);
+        return -1;
+    }
+
+    gsc_cap_poll(&m_events_c2);
+    int index = v4l2_gsc_cap_dqbuf(m_cam_fd2, RECORD_NUM_PLANE);
+    if (!(0 <= index && index < MAX_BUFFERS)) {
+        LOGE("ERR(%s):wrong index = %d", __func__, index);
+        return -1;
+    }
+
+    return index;
+}
+
+int SecCamera::releaseRecordFrame(int index)
+{
+    if (!m_flag_record_start) {
+        /* this can happen when recording frames are returned after
+         * the recording is stopped at the driver level.  we don't
+         * need to return the buffers in this case and we've seen
+         * cases where fimc could crash if we called qbuf and it
+         * wasn't expecting it.
+         */
+        LOGI("%s: recording not in progress, ignoring", __func__);
+        return 0;
+    }
+
+    return v4l2_gsc_cap_qbuf(m_cam_fd2, m_recording_width, m_recording_height, m_buffers_record, index, RECORD_NUM_PLANE);
+}
+
+int SecCamera::setPreviewSize(int width, int height, int pixel_format)
+{
+    LOGV("%s(width(%d), height(%d), format(%d))", __func__, width, height, pixel_format);
+
+    int v4lpixelformat = pixel_format;
+
+#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
+    if (v4lpixelformat == V4L2_PIX_FMT_YUV420)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_YUV420");
+    else if (v4lpixelformat == V4L2_PIX_FMT_YVU420)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420");
+    else if (v4lpixelformat == V4L2_PIX_FMT_YVU420M)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_YVU420M");
+    else if (v4lpixelformat == V4L2_PIX_FMT_NV12)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_NV12");
+    else if (v4lpixelformat == V4L2_PIX_FMT_NV12M)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_NV12M");
+    else if (v4lpixelformat == V4L2_PIX_FMT_NV12T)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_NV12T");
+    else if (v4lpixelformat == V4L2_PIX_FMT_NV21)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_NV21");
+    else if (v4lpixelformat == V4L2_PIX_FMT_YUV422P)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_YUV422P");
+    else if (v4lpixelformat == V4L2_PIX_FMT_YUYV)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_YUYV");
+    else if (v4lpixelformat == V4L2_PIX_FMT_RGB565)
+        LOGV("PreviewFormat:V4L2_PIX_FMT_RGB565");
+    else
+        LOGV("PreviewFormat:UnknownFormat");
+#endif
+    m_preview_width  = width;
+    m_preview_height = height;
+    m_preview_v4lformat = v4lpixelformat;
+
+    return 0;
+}
+
+int SecCamera::getPreviewSize(int *width, int *height, int *frame_size)
+{
+    *width  = m_preview_width;
+    *height = m_preview_height;
+    *frame_size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_preview_v4lformat), *width, *height);
+    return 0;
+}
+
+int SecCamera::getPreviewMaxSize(int *width, int *height)
+{
+    *width  = m_preview_max_width;
+    *height = m_preview_max_height;
+
+    return 0;
+}
+
+int SecCamera::getPreviewPixelFormat(void)
+{
+    return m_preview_v4lformat;
+}
+
+/*
+ * Devide getJpeg() as two funcs, setSnapshotCmd() & getJpeg() because of the shutter sound timing.
+ * Here, just send the capture cmd to camera ISP to start JPEG capture.
+ */
+int SecCamera::setSnapshotCmd(void)
+{
+    LOGV("%s :", __func__);
+
+    int ret = 0;
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return 0;
+    }
+
+    if (m_flag_camera_start > 0) {
+        LOGW("WARN(%s):Camera was in preview, should have been stopped", __func__);
+        stopPreview();
+    }
+
+    memset(&m_events_c, 0, sizeof(m_events_c));
+    m_events_c.fd = m_gsc_vd_fd;
+    m_events_c.events = POLLIN | POLLERR;
+
+    int nframe = 1;
+
+    ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd,m_snapshot_v4lformat);
+    CHECK(ret);
+
+    ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, nframe);
+    CHECK(ret);
+
+#ifdef GAIA_FW_BETA
+    ret = v4l2_gsc_cap_querybuf(m_gsc_vd_fd, &m_capture_buf, V4L2_BUF_TYPE, 1, 2);
+    CHECK(ret);
+#endif
+
+    ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, m_buffers_preview, 0, 1);
+    CHECK(ret);
+
+    ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd);
+    CHECK(ret);
+
+    return 0;
+}
+
+int SecCamera::endSnapshot(void)
+{
+    int ret;
+
+    LOGI("%s :", __func__);
+    if (m_capture_buf.virt.extP[0]) {
+        munmap(m_capture_buf.virt.extP[0], m_capture_buf.size.extS[0]);
+        LOGI("munmap():virt. addr %p size = %d",
+             m_capture_buf.virt.extP[0], m_capture_buf.size.extS[0]);
+        m_capture_buf.virt.extP[0] = NULL;
+        m_capture_buf.size.extS[0] = 0;
+    }
+    return 0;
+}
+
+/*
+ * Set Jpeg quality & exif info and get JPEG data from camera ISP
+ */
+unsigned char* SecCamera::getJpeg(int *jpeg_size, unsigned int *phyaddr)
+{
+    int index, ret = 0;
+    unsigned char *addr;
+    SecBuffer jpegAddr;
+
+    // capture
+    ret = gsc_cap_poll(&m_events_c);
+    CHECK_PTR(ret);
+    index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, 1);
+
+    if (index != 0) {
+        LOGE("ERR(%s):wrong index = %d", __func__, index);
+        return NULL;
+    }
+
+    *jpeg_size = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_MAIN_SIZE);
+    CHECK_PTR(*jpeg_size);
+
+    int main_offset = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_MAIN_OFFSET);
+    CHECK_PTR(main_offset);
+    m_postview_offset = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET);
+    CHECK_PTR(m_postview_offset);
+
+    ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_STREAM_PAUSE, 0);
+    CHECK_PTR(ret);
+    LOGV("\nsnapshot dqueued buffer = %d snapshot_width = %d snapshot_height = %d, size = %d",
+            index, m_snapshot_width, m_snapshot_height, *jpeg_size);
+
+    addr = (unsigned char*)(m_capture_buf.virt.extP[0]) + main_offset;
+    getPreviewAddr(index, &jpegAddr);
+    *phyaddr = jpegAddr.phys.extP[0] + m_postview_offset;
+
+    ret = v4l2_gsc_cap_streamoff(m_gsc_vd_fd);
+    CHECK_PTR(ret);
+
+    return addr;
+}
+
+int SecCamera::getExif(unsigned char *pExifDst, unsigned char *pThumbSrc)
+{
+    /*TODO : to be added HW JPEG code. */
+    return 0;
+}
+
+void SecCamera::getPostViewConfig(int *width, int *height, int *size)
+{
+    *width = m_snapshot_width;
+    *height = m_snapshot_height;
+    *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height);
+    LOGV("[5B] m_preview_width : %d, mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",
+            m_preview_width, *width, *height, *size);
+}
+
+void SecCamera::getThumbnailConfig(int *width, int *height, int *size)
+{
+    *width = m_jpeg_thumbnail_width;
+    *height = m_jpeg_thumbnail_height;
+    *size = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height);
+}
+
+int SecCamera::getPostViewOffset(void)
+{
+    return m_postview_offset;
+}
+
+int SecCamera::getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf,
+                                            unsigned int *output_size)
+{
+    LOGV("%s :", __func__);
+
+    int index;
+    unsigned char *addr;
+    int ret = 0;
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    if (m_flag_camera_start > 0) {
+        LOGW("WARN(%s):Camera was in preview, should have been stopped", __func__);
+        stopPreview();
+    }
+
+    memset(&m_events_c, 0, sizeof(m_events_c));
+    m_events_c.fd = m_gsc_vd_fd;
+    m_events_c.events = POLLIN | POLLERR;
+
+#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
+    if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV420");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12T");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_NV21");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV422P");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_YUYV");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_UYVY");
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565)
+        LOGV("SnapshotFormat:V4L2_PIX_FMT_RGB565");
+    else
+        LOGV("SnapshotFormat:UnknownFormat");
+#endif
+
+    int nframe = 1;
+
+    ret = v4l2_gsc_cap_enum_fmt(m_gsc_vd_fd, m_snapshot_v4lformat);
+    CHECK(ret);
+
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+    LOGV("Internal_is(%d), %s", Internal_is, (const char*)getCameraSensorName());
+
+    ret = v4l2_gsc_cap_s_fmt_cap(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat);
+    CHECK(ret);
+
+    ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CACHEABLE, 1);
+    CHECK(ret);
+    ret = v4l2_gsc_cap_reqbufs(m_gsc_vd_fd, V4L2_BUF_TYPE, nframe);
+    CHECK(ret);
+
+#ifdef GAIA_FW_BETA
+    ret = v4l2_gsc_cap_querybuf(m_gsc_vd_fd, &m_capture_buf, V4L2_BUF_TYPE, 1, 2);
+    CHECK(ret);
+#endif
+
+    struct SecBuffer my_buf;
+    my_buf.virt.p = (char *)yuv_buf;
+
+#ifndef GAIA_FW_BETA
+    ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, &my_buf, 0, 1);
+    CHECK(ret);
+#else
+    ret = v4l2_gsc_cap_qbuf(m_gsc_vd_fd, m_snapshot_width, m_snapshot_height, &m_capture_buf, 0, 1);
+    CHECK(ret);
+#endif
+
+    ret = v4l2_gsc_cap_streamon(m_gsc_vd_fd);
+    CHECK(ret);
+
+    gsc_cap_poll(&m_events_c);
+
+    index = v4l2_gsc_cap_dqbuf(m_gsc_vd_fd, 1);
+
+#ifdef GAIA_FW_BETA
+    ret = v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_STREAM_PAUSE, 0);
+    CHECK_PTR(ret);
+    LOGV("\nsnapshot dequeued buffer = %d snapshot_width = %d snapshot_height = %d",
+            index, m_snapshot_width, m_snapshot_height);
+
+    yuv_buf = (unsigned char*)m_capture_buf.virt.extP[0];
+#endif
+    m_picture_vaddr = yuv_buf;
+    v4l2_gsc_cap_streamoff(m_gsc_vd_fd);
+
+    /* TODO: JPEG encode for smdk5250 */
+
+    return 0;
+}
+
+int SecCamera::setSnapshotSize(int width, int height)
+{
+    LOGV("%s(width(%d), height(%d))", __func__, width, height);
+
+    m_snapshot_width  = width;
+    m_snapshot_height = height;
+
+    return 0;
+}
+
+int SecCamera::getSnapshotSize(int *width, int *height, int *frame_size)
+{
+    *width  = m_snapshot_width;
+    *height = m_snapshot_height;
+
+    int frame = 0;
+
+    frame = FRAME_SIZE(V4L2_PIX_2_HAL_PIXEL_FORMAT(m_snapshot_v4lformat), *width, *height);
+
+    // set it big.
+    if (frame == 0)
+        frame = m_snapshot_width * m_snapshot_height * BPP;
+
+    *frame_size = frame;
+
+    return 0;
+}
+
+int SecCamera::getSnapshotMaxSize(int *width, int *height)
+{
+    switch (m_camera_id) {
+    case CAMERA_ID_FRONT:
+        m_snapshot_max_width  = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH;
+        m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT;
+        break;
+
+    default:
+    case CAMERA_ID_BACK:
+        m_snapshot_max_width  = MAX_BACK_CAMERA_SNAPSHOT_WIDTH;
+        m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT;
+        break;
+    }
+
+    *width  = m_snapshot_max_width;
+    *height = m_snapshot_max_height;
+
+    return 0;
+}
+
+int SecCamera::setSnapshotPixelFormat(int pixel_format)
+{
+    int v4lpixelformat = pixel_format;
+
+    if (m_snapshot_v4lformat != v4lpixelformat) {
+        m_snapshot_v4lformat = v4lpixelformat;
+    }
+
+#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
+    if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420)
+        LOGE("%s : SnapshotFormat:V4L2_PIX_FMT_YUV420", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV12T", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_NV21)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_NV21", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUV422P", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_YUYV", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_UYVY", __func__);
+    else if (m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565)
+        LOGD("%s : SnapshotFormat:V4L2_PIX_FMT_RGB565", __func__);
+    else
+        LOGD("SnapshotFormat:UnknownFormat");
+#endif
+    return 0;
+}
+
+int SecCamera::getSnapshotPixelFormat(void)
+{
+    return m_snapshot_v4lformat;
+}
+
+int SecCamera::getCameraId(void)
+{
+    return m_camera_id;
+}
+
+int SecCamera::setAutofocus(void)
+{
+    LOGV("%s :", __func__);
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::getAutoFocusResult(void)
+{
+    int af_result;
+
+    af_result = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT);
+
+    LOGV("%s : returning %d", __func__, af_result);
+
+    return af_result;
+}
+
+int SecCamera::cancelAutofocus(void)
+{
+    LOGV("%s :", __func__);
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::SetRotate(int angle)
+{
+    LOGE("%s(angle(%d))", __func__, angle);
+
+    if (m_angle != angle) {
+        switch (angle) {
+        case -360:
+        case    0:
+        case  360:
+            m_angle = 0;
+            break;
+
+        case -270:
+        case   90:
+            m_angle = 90;
+            break;
+
+        case -180:
+        case  180:
+            m_angle = 180;
+            break;
+
+        case  -90:
+        case  270:
+            m_angle = 270;
+            break;
+
+        default:
+            LOGE("ERR(%s):Invalid angle(%d)", __func__, angle);
+            return -1;
+        }
+
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_ROTATION, angle) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_ROTATION", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getRotate(void)
+{
+    LOGV("%s : angle(%d)", __func__, m_angle);
+    return m_angle;
+}
+
+int SecCamera::setFrameRate(int frame_rate)
+{
+    LOGV("%s(FrameRate(%d))", __func__, frame_rate);
+
+    if (frame_rate < FRAME_RATE_AUTO || FRAME_RATE_MAX < frame_rate )
+        LOGE("ERR(%s):Invalid frame_rate(%d)", __func__, frame_rate);
+
+    m_params->capture.timeperframe.denominator = frame_rate;
+    if (m_flag_camera_start) {
+        if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FRAME_RATE, frame_rate) < 0) {
+            LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FRAME_RATE", __func__);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::setVerticalMirror(void)
+{
+    LOGV("%s :", __func__);
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_VFLIP, 0) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_VFLIP", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::setHorizontalMirror(void)
+{
+    LOGV("%s :", __func__);
+
+    if (m_gsc_vd_fd <= 0) {
+        LOGE("ERR(%s):Camera was closed", __func__);
+        return -1;
+    }
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_HFLIP, 0) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_HFLIP", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::setWhiteBalance(int white_balance)
+{
+    LOGV("%s(white_balance(%d))", __func__, white_balance);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (white_balance < IS_AWB_AUTO || IS_AWB_MAX <= white_balance) {
+            LOGE("ERR(%s):Invalid white_balance(%d)", __func__, white_balance);
+            return -1;
+        }
+    } else {
+        if (white_balance <= WHITE_BALANCE_BASE || WHITE_BALANCE_MAX <= white_balance) {
+            LOGE("ERR(%s):Invalid white_balance(%d)", __func__, white_balance);
+            return -1;
+        }
+    }
+
+    if (m_params->white_balance != white_balance) {
+        m_params->white_balance = white_balance;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_AWB_MODE, white_balance) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_AWB_MODE", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_WHITE_BALANCE, white_balance) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WHITE_BALANCE", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getWhiteBalance(void)
+{
+    LOGV("%s : white_balance(%d)", __func__, m_params->white_balance);
+    return m_params->white_balance;
+}
+
+int SecCamera::setBrightness(int brightness)
+{
+    LOGV("%s(brightness(%d))", __func__, brightness);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        brightness += IS_BRIGHTNESS_DEFAULT;
+        if (brightness < IS_BRIGHTNESS_MINUS_2 || IS_BRIGHTNESS_PLUS2 < brightness) {
+            LOGE("ERR(%s):Invalid brightness(%d)", __func__, brightness);
+            return -1;
+        }
+    } else {
+        LOGW("WARN(%s):Not supported brightness setting", __func__);
+        return 0;
+    }
+
+    if (m_params->brightness != brightness) {
+        m_params->brightness = brightness;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_BRIGHTNESS, brightness) < EV_MINUS_4) {
+                LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_BRIGHTNESS", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getBrightness(void)
+{
+    LOGV("%s : brightness(%d)", __func__, m_params->brightness);
+    return m_params->brightness;
+}
+
+int SecCamera::setExposure(int exposure)
+{
+    LOGV("%s(exposure(%d))", __func__, exposure);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        exposure += IS_EXPOSURE_DEFAULT;
+        if (exposure < IS_EXPOSURE_MINUS_2 || IS_EXPOSURE_PLUS2 < exposure) {
+            LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure);
+            return -1;
+        }
+    } else {
+        exposure += EV_DEFAULT;
+        if (exposure < EV_MINUS_4 || EV_PLUS_4 < exposure) {
+            LOGE("ERR(%s):Invalid exposure(%d)", __func__, exposure);
+            return -1;
+        }
+    }
+
+    if (m_params->exposure != exposure) {
+        m_params->exposure = exposure;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_EXPOSURE, exposure) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_EXPOSURE", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BRIGHTNESS, exposure) < EV_MINUS_4) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BRIGHTNESS", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getExposure(void)
+{
+    LOGV("%s : exposure(%d)", __func__, m_params->exposure);
+    return m_params->exposure;
+}
+
+int SecCamera::setImageEffect(int image_effect)
+{
+    LOGV("%s(image_effect(%d))", __func__, image_effect);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (image_effect < IS_IMAGE_EFFECT_DISABLE || IS_IMAGE_EFFECT_MAX <= image_effect) {
+            LOGE("ERR(%s):Invalid image_effect(%d)", __func__, image_effect);
+            return -1;
+        }
+    } else {
+        if (image_effect <= IMAGE_EFFECT_BASE || IMAGE_EFFECT_MAX <= image_effect) {
+            LOGE("ERR(%s):Invalid image_effect(%d)", __func__, image_effect);
+            return -1;
+        }
+    }
+
+    if (m_params->effects != image_effect) {
+        m_params->effects = image_effect;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_IMAGE_EFFECT, image_effect) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_IMAGE_EFFECT", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_EFFECT, image_effect) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_EFFECT", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getImageEffect(void)
+{
+    LOGV("%s : image_effect(%d)", __func__, m_params->effects);
+    return m_params->effects;
+}
+
+int SecCamera::setAntiBanding(int anti_banding)
+{
+    LOGV("%s(anti_banding(%d))", __func__, anti_banding);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (anti_banding < IS_AFC_DISABLE || IS_AFC_MAX <= anti_banding) {
+            LOGE("ERR(%s):Invalid anti_banding (%d)", __func__, anti_banding);
+            return -1;
+        }
+    } else {
+        if (anti_banding < ANTI_BANDING_AUTO || ANTI_BANDING_OFF < anti_banding) {
+            LOGE("ERR(%s):Invalid anti_banding (%d)", __func__, anti_banding);
+            return -1;
+        }
+    }
+
+    if (m_anti_banding != anti_banding) {
+        m_anti_banding = anti_banding;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_AFC_MODE, anti_banding) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_AFC_MODE", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ANTI_BANDING, anti_banding) < 0) {
+                     LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_BANDING", __func__);
+                     return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::setSceneMode(int scene_mode)
+{
+    LOGV("%s(scene_mode(%d))", __func__, scene_mode);
+
+    if (scene_mode <= SCENE_MODE_BASE || SCENE_MODE_MAX <= scene_mode) {
+        LOGE("ERR(%s):Invalid scene_mode (%d)", __func__, scene_mode);
+        return -1;
+    }
+
+    if (m_params->scene_mode != scene_mode) {
+        m_params->scene_mode = scene_mode;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SCENE_MODE, scene_mode) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SCENE_MODE", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getSceneMode(void)
+{
+    return m_params->scene_mode;
+}
+
+int SecCamera::setFlashMode(int flash_mode)
+{
+    LOGV("%s(flash_mode(%d))", __func__, flash_mode);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (flash_mode <= IS_FLASH_MODE_OFF || IS_FLASH_MODE_MAX <= flash_mode) {
+            LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode);
+            return -1;
+        }
+    } else {
+        if (flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) {
+            LOGE("ERR(%s):Invalid flash_mode (%d)", __func__, flash_mode);
+            return -1;
+        }
+    }
+
+    if (m_params->flash_mode != flash_mode) {
+        m_params->flash_mode = flash_mode;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FLASH_MODE, flash_mode) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FLASH_MODE", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getFlashMode(void)
+{
+    return m_params->flash_mode;
+}
+
+int SecCamera::setISO(int iso_value)
+{
+    LOGV("%s(iso_value(%d))", __func__, iso_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (iso_value < IS_ISO_AUTO || IS_ISO_MAX <= iso_value) {
+            LOGE("ERR(%s):Invalid iso_value (%d)", __func__, iso_value);
+            return -1;
+        }
+    } else {
+        if (iso_value < ISO_AUTO || ISO_MAX <= iso_value) {
+            LOGE("ERR(%s):Invalid iso_value (%d)", __func__, iso_value);
+            return -1;
+        }
+    }
+
+    if (m_params->iso != iso_value) {
+        m_params->iso = iso_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_ISO, iso_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_ISO", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ISO, iso_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ISO", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getISO(void)
+{
+    return m_params->iso;
+}
+
+int SecCamera::setContrast(int contrast_value)
+{
+    LOGV("%s(contrast_value(%d))", __func__, contrast_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (contrast_value < IS_CONTRAST_AUTO || IS_CONTRAST_MAX <= contrast_value) {
+            LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value);
+            return -1;
+        }
+    } else {
+        if (contrast_value < CONTRAST_MINUS_2 || CONTRAST_MAX <= contrast_value) {
+            LOGE("ERR(%s):Invalid contrast_value (%d)", __func__, contrast_value);
+            return -1;
+        }
+    }
+
+    if (m_params->contrast != contrast_value) {
+        m_params->contrast = contrast_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_CONTRAST, contrast_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_CONTRAST", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_CONTRAST, contrast_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CONTRAST", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getContrast(void)
+{
+    return m_params->contrast;
+}
+
+int SecCamera::setSaturation(int saturation_value)
+{
+    LOGV("%s(saturation_value(%d))", __func__, saturation_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        saturation_value += IS_SATURATION_DEFAULT;
+        if (saturation_value < IS_SATURATION_MINUS_2 || IS_SATURATION_MAX <= saturation_value) {
+            LOGE("ERR(%s):Invalid saturation_value (%d)", __func__, saturation_value);
+            return -1;
+        }
+    } else {
+        saturation_value += SATURATION_DEFAULT;
+        if (saturation_value < SATURATION_MINUS_2 || SATURATION_MAX <= saturation_value) {
+            LOGE("ERR(%s):Invalid saturation_value (%d)", __func__, saturation_value);
+            return -1;
+        }
+    }
+
+    if (m_params->saturation != saturation_value) {
+        m_params->saturation = saturation_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_SATURATION, saturation_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SATURATION, saturation_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getSaturation(void)
+{
+    return m_params->saturation;
+}
+
+int SecCamera::setSharpness(int sharpness_value)
+{
+    LOGV("%s(sharpness_value(%d))", __func__, sharpness_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        sharpness_value += IS_SHARPNESS_DEFAULT;
+        if (sharpness_value < IS_SHARPNESS_MINUS_2 || IS_SHARPNESS_MAX <= sharpness_value) {
+            LOGE("ERR(%s):Invalid sharpness_value (%d)", __func__, sharpness_value);
+            return -1;
+        }
+    } else {
+        sharpness_value += SHARPNESS_DEFAULT;
+        if (sharpness_value < SHARPNESS_MINUS_2 || SHARPNESS_MAX <= sharpness_value) {
+            LOGE("ERR(%s):Invalid sharpness_value (%d)", __func__, sharpness_value);
+            return -1;
+        }
+    }
+
+    if (m_params->sharpness != sharpness_value) {
+        m_params->sharpness = sharpness_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_SHARPNESS, sharpness_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SHARPNESS, sharpness_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getSharpness(void)
+{
+    return m_params->sharpness;
+}
+
+int SecCamera::setHue(int hue_value)
+{
+    LOGV("%s(hue_value(%d))", __func__, hue_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        hue_value += IS_HUE_DEFAULT;
+        if (hue_value < IS_HUE_MINUS_2 || IS_HUE_MAX <= hue_value) {
+            LOGE("ERR(%s):Invalid hue_value (%d)", __func__, hue_value);
+            return -1;
+        }
+    } else {
+            LOGW("WARN(%s):Not supported hue setting", __func__);
+            return 0;
+    }
+
+    if (m_params->hue != hue_value) {
+        m_params->hue = hue_value;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_HUE, hue_value) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_HUE", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getHue(void)
+{
+    return m_params->hue;
+}
+
+int SecCamera::setWDR(int wdr_value)
+{
+    LOGV("%s(wdr_value(%d))", __func__, wdr_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (wdr_value < IS_DRC_BYPASS_DISABLE || IS_DRC_BYPASS_MAX <= wdr_value) {
+            LOGE("ERR(%s):Invalid drc_value (%d)", __func__, wdr_value);
+            return -1;
+        }
+    } else {
+        if (wdr_value < WDR_OFF || WDR_MAX <= wdr_value) {
+            LOGE("ERR(%s):Invalid wdr_value (%d)", __func__, wdr_value);
+            return -1;
+        }
+    }
+
+    if (m_wdr != wdr_value) {
+        m_wdr = wdr_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_SET_DRC, wdr_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_SET_DRC", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_WDR, wdr_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WDR", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getWDR(void)
+{
+    return m_wdr;
+}
+
+int SecCamera::setAntiShake(int anti_shake)
+{
+    LOGV("%s(anti_shake(%d))", __func__, anti_shake);
+
+    if (anti_shake < ANTI_SHAKE_OFF || ANTI_SHAKE_MAX <= anti_shake) {
+        LOGE("ERR(%s):Invalid anti_shake (%d)", __func__, anti_shake);
+        return -1;
+    }
+
+    if (m_anti_shake != anti_shake) {
+        m_anti_shake = anti_shake;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ANTI_SHAKE, anti_shake) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_SHAKE", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getAntiShake(void)
+{
+    return m_anti_shake;
+}
+
+int SecCamera::setMetering(int metering_value)
+{
+    LOGV("%s(metering (%d))", __func__, metering_value);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (metering_value < IS_METERING_AVERAGE || IS_METERING_MAX <= metering_value) {
+            LOGE("ERR(%s):Invalid metering_value (%d)", __func__, metering_value);
+            return -1;
+        }
+    } else {
+        if (metering_value <= METERING_BASE || METERING_MAX <= metering_value) {
+            LOGE("ERR(%s):Invalid metering_value (%d)", __func__, metering_value);
+            return -1;
+        }
+    }
+
+    if (m_params->metering != metering_value) {
+        m_params->metering = metering_value;
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_METERING, metering_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_METERING", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_METERING, metering_value) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_METERING", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getMetering(void)
+{
+    return m_params->metering;
+}
+
+int SecCamera::setJpegQuality(int jpeg_quality)
+{
+    LOGV("%s(jpeg_quality (%d))", __func__, jpeg_quality);
+
+    if (jpeg_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_quality) {
+        LOGE("ERR(%s):Invalid jpeg_quality (%d)", __func__, jpeg_quality);
+        return -1;
+    }
+
+    if (m_jpeg_quality != jpeg_quality) {
+        m_jpeg_quality = jpeg_quality;
+#ifdef JPEG_FROM_SENSOR
+        if (m_flag_camera_start && (m_camera_id == CAMERA_ID_BACK)) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAM_JPEG_QUALITY", __func__);
+                return -1;
+            }
+        }
+#endif
+    }
+
+    return 0;
+}
+
+int SecCamera::getJpegQuality(void)
+{
+    return m_jpeg_quality;
+}
+
+int SecCamera::setZoom(int zoom_level)
+{
+    LOGV("%s(zoom_level (%d))", __func__, zoom_level);
+
+    if (zoom_level < ZOOM_LEVEL_0 || ZOOM_LEVEL_MAX <= zoom_level) {
+        LOGE("ERR(%s):Invalid zoom_level (%d)", __func__, zoom_level);
+        return -1;
+    }
+
+    if (m_zoom_level != zoom_level) {
+        m_zoom_level = zoom_level;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_ZOOM, zoom_level) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ZOOM", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getZoom(void)
+{
+    return m_zoom_level;
+}
+
+int SecCamera::setObjectTracking(int object_tracking)
+{
+    LOGV("%s(object_tracking (%d))", __func__, object_tracking);
+
+    if (object_tracking < OBJECT_TRACKING_OFF || OBJECT_TRACKING_MAX <= object_tracking) {
+        LOGE("ERR(%s):Invalid object_tracking (%d)", __func__, object_tracking);
+        return -1;
+    }
+
+    if (m_object_tracking != object_tracking)
+        m_object_tracking = object_tracking;
+
+    return 0;
+}
+
+int SecCamera::getObjectTracking(void)
+{
+    return m_object_tracking;
+}
+
+int SecCamera::getObjectTrackingStatus(void)
+{
+    int obj_status = 0;
+    obj_status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJ_TRACKING_STATUS);
+    return obj_status;
+}
+
+int SecCamera::setObjectTrackingStartStop(int start_stop)
+{
+    LOGV("%s(object_tracking_start_stop (%d))", __func__, start_stop);
+
+    if (m_object_tracking_start_stop != start_stop) {
+        m_object_tracking_start_stop = start_stop;
+        if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP, start_stop) < 0) {
+            LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP", __func__);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::setTouchAFStartStop(int start_stop)
+{
+    LOGV("%s(touch_af_start_stop (%d))", __func__, start_stop);
+
+    if (m_touch_af_start_stop != start_stop) {
+        m_touch_af_start_stop = start_stop;
+        if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_TOUCH_AF_START_STOP, start_stop) < 0) {
+            LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_TOUCH_AF_START_STOP", __func__);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::setSmartAuto(int smart_auto)
+{
+    LOGV("%s(smart_auto (%d))", __func__, smart_auto);
+
+    if (smart_auto < SMART_AUTO_OFF || SMART_AUTO_MAX <= smart_auto) {
+        LOGE("ERR(%s):Invalid smart_auto (%d)", __func__, smart_auto);
+        return -1;
+    }
+
+    if (m_smart_auto != smart_auto) {
+        m_smart_auto = smart_auto;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SMART_AUTO, smart_auto) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SMART_AUTO", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getSmartAuto(void)
+{
+    return m_smart_auto;
+}
+
+int SecCamera::getAutosceneStatus(void)
+{
+    int autoscene_status = -1;
+
+    if (getSmartAuto() == SMART_AUTO_ON) {
+        autoscene_status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SMART_AUTO_STATUS);
+
+        if ((autoscene_status < SMART_AUTO_STATUS_AUTO) || (autoscene_status > SMART_AUTO_STATUS_MAX)) {
+            LOGE("ERR(%s):Invalid getAutosceneStatus (%d)", __func__, autoscene_status);
+            return -1;
+        }
+    }
+    return autoscene_status;
+}
+
+int SecCamera::setBeautyShot(int beauty_shot)
+{
+    LOGV("%s(beauty_shot (%d))", __func__, beauty_shot);
+
+    if (beauty_shot < BEAUTY_SHOT_OFF || BEAUTY_SHOT_MAX <= beauty_shot) {
+        LOGE("ERR(%s):Invalid beauty_shot (%d)", __func__, beauty_shot);
+        return -1;
+    }
+
+    if (m_beauty_shot != beauty_shot) {
+        m_beauty_shot = beauty_shot;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BEAUTY_SHOT, beauty_shot) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BEAUTY_SHOT", __func__);
+                return -1;
+            }
+        }
+
+        setFaceDetect(FACE_DETECTION_ON_BEAUTY);
+    }
+
+    return 0;
+}
+
+int SecCamera::getBeautyShot(void)
+{
+    return m_beauty_shot;
+}
+
+int SecCamera::setVintageMode(int vintage_mode)
+{
+    LOGV("%s(vintage_mode(%d))", __func__, vintage_mode);
+
+    if (vintage_mode <= VINTAGE_MODE_BASE || VINTAGE_MODE_MAX <= vintage_mode) {
+        LOGE("ERR(%s):Invalid vintage_mode (%d)", __func__, vintage_mode);
+        return -1;
+    }
+
+    if (m_vintage_mode != vintage_mode) {
+        m_vintage_mode = vintage_mode;
+        if (m_flag_camera_start) {
+            if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_VINTAGE_MODE, vintage_mode) < 0) {
+                LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_VINTAGE_MODE", __func__);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getVintageMode(void)
+{
+    return m_vintage_mode;
+}
+
+int SecCamera::setFocusMode(int focus_mode)
+{
+    LOGV("%s(focus_mode(%d))", __func__, focus_mode);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (Internal_is) {
+        if (IS_FOCUS_MODE_MAX <= focus_mode) {
+            LOGE("ERR(%s):Invalid focus_mode (%d)", __func__, focus_mode);
+            return -1;
+        }
+    } else {
+        if (FOCUS_MODE_MAX <= focus_mode) {
+            LOGE("ERR(%s):Invalid focus_mode (%d)", __func__, focus_mode);
+            return -1;
+        }
+    }
+
+    if (m_params->focus_mode != focus_mode) {
+        m_params->focus_mode = focus_mode;
+#ifdef AF_SUPPORT
+        if (m_flag_camera_start) {
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FOCUS_MODE, focus_mode) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FOCUS_MODE", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __func__);
+                    return -1;
+                }
+            }
+        }
+#endif
+    }
+
+    return 0;
+}
+
+int SecCamera::getFocusMode(void)
+{
+    return m_params->focus_mode;
+}
+
+int SecCamera::setFaceDetect(int face_detect)
+{
+    LOGV("%s(face_detect(%d))", __func__, face_detect);
+    int Internal_is = !strncmp((const char*)getCameraSensorName(), "ISP Camera", 10);
+
+    if (m_face_detect != face_detect) {
+        m_face_detect = face_detect;
+        if (m_flag_camera_start) {
+            if (m_face_detect != FACE_DETECTION_OFF) {
+                if (Internal_is) {
+                    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CAMERA_FOCUS_MODE, IS_FOCUS_MODE_AUTO) < 0) {
+                        LOGE("ERR(%s):Fail on V4L2_CID_IS_CAMERA_FOCUS_MODin face detecion", __func__);
+                        return -1;
+                    }
+                } else {
+                    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_AUTO) < 0) {
+                        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODin face detecion", __func__);
+                        return -1;
+                    }
+                }
+            }
+            if (Internal_is) {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_IS_CMD_FD, face_detect) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_IS_CMD_FD", __func__);
+                    return -1;
+                }
+            } else {
+                if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FACE_DETECTION, face_detect) < 0) {
+                    LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACE_DETECTION", __func__);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+int SecCamera::getFaceDetect(void)
+{
+    return m_face_detect;
+}
+
+int SecCamera::setGPSLatitude(const char *gps_latitude)
+{
+    double conveted_latitude = 0;
+    LOGV("%s(gps_latitude(%s))", __func__, gps_latitude);
+    if (gps_latitude == NULL)
+        m_gps_latitude = 0;
+    else {
+        conveted_latitude = atof(gps_latitude);
+        m_gps_latitude = (long)(conveted_latitude * 10000 / 1);
+    }
+
+    LOGV("%s(m_gps_latitude(%ld))", __func__, m_gps_latitude);
+    return 0;
+}
+
+int SecCamera::setGPSLongitude(const char *gps_longitude)
+{
+    double conveted_longitude = 0;
+    LOGV("%s(gps_longitude(%s))", __func__, gps_longitude);
+    if (gps_longitude == NULL)
+        m_gps_longitude = 0;
+    else {
+        conveted_longitude = atof(gps_longitude);
+        m_gps_longitude = (long)(conveted_longitude * 10000 / 1);
+    }
+
+    LOGV("%s(m_gps_longitude(%ld))", __func__, m_gps_longitude);
+    return 0;
+}
+
+int SecCamera::setGPSAltitude(const char *gps_altitude)
+{
+    double conveted_altitude = 0;
+    LOGV("%s(gps_altitude(%s))", __func__, gps_altitude);
+    if (gps_altitude == NULL)
+        m_gps_altitude = 0;
+    else {
+        conveted_altitude = atof(gps_altitude);
+        m_gps_altitude = (long)(conveted_altitude * 100 / 1);
+    }
+
+    LOGV("%s(m_gps_altitude(%ld))", __func__, m_gps_altitude);
+    return 0;
+}
+
+int SecCamera::setGPSTimeStamp(const char *gps_timestamp)
+{
+    LOGV("%s(gps_timestamp(%s))", __func__, gps_timestamp);
+    if (gps_timestamp == NULL)
+        m_gps_timestamp = 0;
+    else
+        m_gps_timestamp = atol(gps_timestamp);
+
+    LOGV("%s(m_gps_timestamp(%ld))", __func__, m_gps_timestamp);
+    return 0;
+}
+
+int SecCamera::setGPSProcessingMethod(const char *gps_processing_method)
+{
+    LOGV("%s(gps_processing_method(%s))", __func__, gps_processing_method);
+    memset(mExifInfo.gps_processing_method, 0, sizeof(mExifInfo.gps_processing_method));
+    if (gps_processing_method != NULL) {
+        size_t len = strlen(gps_processing_method);
+        if (len > sizeof(mExifInfo.gps_processing_method)) {
+            len = sizeof(mExifInfo.gps_processing_method);
+        }
+        memcpy(mExifInfo.gps_processing_method, gps_processing_method, len);
+    }
+    return 0;
+}
+
+int SecCamera::setFaceDetectLockUnlock(int facedetect_lockunlock)
+{
+    LOGV("%s(facedetect_lockunlock(%d))", __func__, facedetect_lockunlock);
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, facedetect_lockunlock) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::setObjectPosition(int x, int y)
+{
+    LOGV("%s(setObjectPosition(x=%d, y=%d))", __func__, x, y);
+
+    if (m_preview_width ==640)
+        x = x - 80;
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, x) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_X", __func__);
+        return -1;
+    }
+
+    if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, y) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_Y", __func__);
+        return -1;
+    }
+
+    return 0;
+}
+
+int SecCamera::setGamma(int gamma)
+{
+     LOGV("%s(gamma(%d))", __func__, gamma);
+
+     if (gamma < GAMMA_OFF || GAMMA_MAX <= gamma) {
+         LOGE("ERR(%s):Invalid gamma (%d)", __func__, gamma);
+         return -1;
+     }
+
+     if (m_video_gamma != gamma) {
+         m_video_gamma = gamma;
+         if (m_flag_camera_start) {
+             if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_GAMMA, gamma) < 0) {
+                 LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_GAMMA", __func__);
+                 return -1;
+             }
+         }
+     }
+
+     return 0;
+}
+
+int SecCamera::setSlowAE(int slow_ae)
+{
+     LOGV("%s(slow_ae(%d))", __func__, slow_ae);
+
+     if (slow_ae < GAMMA_OFF || GAMMA_MAX <= slow_ae) {
+         LOGE("ERR(%s):Invalid slow_ae (%d)", __func__, slow_ae);
+         return -1;
+     }
+
+     if (m_slow_ae!= slow_ae) {
+         m_slow_ae = slow_ae;
+         if (m_flag_camera_start) {
+             if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_SET_SLOW_AE, slow_ae) < 0) {
+                 LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_SLOW_AE", __func__);
+                 return -1;
+             }
+         }
+     }
+
+     return 0;
+}
+
+int SecCamera::setRecording(int recording_en)
+{
+     LOGV("%s(recoding_en(%d))", __func__, recording_en);
+
+     m_recording_en  = recording_en;
+
+     return 0;
+}
+
+int SecCamera::setRecordingSize(int width, int height)
+{
+     LOGV("%s(width(%d), height(%d))", __func__, width, height);
+
+     m_recording_width  = width;
+     m_recording_height = height;
+
+     return 0;
+}
+
+int SecCamera::getRecordingSize(int *width, int *height)
+{
+    *width  = m_recording_width;
+    *height = m_recording_height;
+
+    return 0;
+}
+
+int SecCamera::setExifOrientationInfo(int orientationInfo)
+{
+     LOGV("%s(orientationInfo(%d))", __func__, orientationInfo);
+
+     if (orientationInfo < 0) {
+         LOGE("ERR(%s):Invalid orientationInfo (%d)", __func__, orientationInfo);
+         return -1;
+     }
+     m_exif_orientation = orientationInfo;
+
+     return 0;
+}
+
+int SecCamera::setBatchReflection()
+{
+    if (m_flag_camera_start) {
+        if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_BATCH_REFLECTION, 1) < 0) {
+             LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BATCH_REFLECTION", __func__);
+             return -1;
+        }
+    }
+
+    return 0;
+}
+
+/* Camcorder fix fps */
+int SecCamera::setSensorMode(int sensor_mode)
+{
+    LOGV("%s(sensor_mode (%d))", __func__, sensor_mode);
+
+    if (sensor_mode < SENSOR_MODE_CAMERA || SENSOR_MODE_MOVIE < sensor_mode) {
+        LOGE("ERR(%s):Invalid sensor mode (%d)", __func__, sensor_mode);
+        return -1;
+    }
+
+    if (m_sensor_mode != sensor_mode)
+        m_sensor_mode = sensor_mode;
+
+    return 0;
+}
+
+/*  Shot mode   */
+/*  SINGLE = 0
+*   CONTINUOUS = 1
+*   PANORAMA = 2
+*   SMILE = 3
+*   SELF = 6
+*/
+int SecCamera::setShotMode(int shot_mode)
+{
+    LOGV("%s(shot_mode (%d))", __func__, shot_mode);
+    if (shot_mode < SHOT_MODE_SINGLE || SHOT_MODE_SELF < shot_mode) {
+        LOGE("ERR(%s):Invalid shot_mode (%d)", __func__, shot_mode);
+        return -1;
+    }
+    m_shot_mode = shot_mode;
+
+    return 0;
+}
+
+int SecCamera::setDataLineCheck(int chk_dataline)
+{
+    LOGV("%s(chk_dataline (%d))", __func__, chk_dataline);
+
+    if (chk_dataline < CHK_DATALINE_OFF || CHK_DATALINE_MAX <= chk_dataline) {
+        LOGE("ERR(%s):Invalid chk_dataline (%d)", __func__, chk_dataline);
+        return -1;
+    }
+
+    m_chk_dataline = chk_dataline;
+
+    return 0;
+}
+
+int SecCamera::getDataLineCheck(void)
+{
+    return m_chk_dataline;
+}
+
+int SecCamera::setDataLineCheckStop(void)
+{
+    LOGV("%s", __func__);
+
+    if (m_flag_camera_start) {
+        if (v4l2_gsc_cap_s_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_CHECK_DATALINE_STOP, 1) < 0) {
+            LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CHECK_DATALINE_STOP", __func__);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+const __u8* SecCamera::getCameraSensorName(void)
+{
+    LOGV("%s", __func__);
+
+    return v4l2_gsc_cap_enuminput(m_gsc_vd_fd, getCameraId());
+}
+
+#ifdef ENABLE_ESD_PREVIEW_CHECK
+int SecCamera::getCameraSensorESDStatus(void)
+{
+    LOGV("%s", __func__);
+
+    // 0 : normal operation, 1 : abnormal operation
+    int status = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_ESD_INT);
+
+    return status;
+}
+#endif // ENABLE_ESD_PREVIEW_CHECK
+
+int SecCamera::setJpegThumbnailSize(int width, int height)
+{
+    LOGV("%s(width(%d), height(%d))", __func__, width, height);
+
+    m_jpeg_thumbnail_width  = width;
+    m_jpeg_thumbnail_height = height;
+
+    return 0;
+}
+
+int SecCamera::getJpegThumbnailSize(int *width, int  *height)
+{
+    if (width)
+        *width   = m_jpeg_thumbnail_width;
+    if (height)
+        *height  = m_jpeg_thumbnail_height;
+
+    return 0;
+}
+
+int SecCamera::setJpegThumbnailQuality(int jpeg_thumbnail_quality)
+{
+    LOGV("%s(jpeg_thumbnail_quality (%d))", __func__, jpeg_thumbnail_quality);
+
+    if (jpeg_thumbnail_quality < JPEG_QUALITY_ECONOMY || JPEG_QUALITY_MAX <= jpeg_thumbnail_quality) {
+        LOGE("ERR(%s):Invalid jpeg_thumbnail_quality (%d)", __func__, jpeg_thumbnail_quality);
+        return -1;
+    }
+
+    if (m_jpeg_thumbnail_quality != jpeg_thumbnail_quality) {
+        m_jpeg_thumbnail_quality = jpeg_thumbnail_quality;
+    }
+
+    return 0;
+}
+
+int SecCamera::getJpegThumbnailQuality(void)
+{
+    return m_jpeg_thumbnail_quality;
+}
+
+void SecCamera::setExifFixedAttribute()
+{
+    char property[PROPERTY_VALUE_MAX];
+
+    //2 0th IFD TIFF Tags
+    //3 Maker
+    property_get("ro.product.brand", property, EXIF_DEF_MAKER);
+    strncpy((char *)mExifInfo.maker, property,
+                sizeof(mExifInfo.maker) - 1);
+    mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0';
+    //3 Model
+    property_get("ro.product.model", property, EXIF_DEF_MODEL);
+    strncpy((char *)mExifInfo.model, property,
+                sizeof(mExifInfo.model) - 1);
+    mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0';
+    //3 Software
+    property_get("ro.build.id", property, EXIF_DEF_SOFTWARE);
+    strncpy((char *)mExifInfo.software, property,
+                sizeof(mExifInfo.software) - 1);
+    mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0';
+
+    //3 YCbCr Positioning
+    mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING;
+
+    //2 0th IFD Exif Private Tags
+    //3 F Number
+    mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM;
+    mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN;
+    //3 Exposure Program
+    mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM;
+    //3 Exif Version
+    memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version));
+    //3 Aperture
+    uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den);
+    mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN;
+    mExifInfo.aperture.den = EXIF_DEF_APEX_DEN;
+    //3 Maximum lens aperture
+    mExifInfo.max_aperture.num = mExifInfo.aperture.num;
+    mExifInfo.max_aperture.den = mExifInfo.aperture.den;
+    //3 Lens Focal Length
+    if (m_camera_id == CAMERA_ID_BACK)
+        mExifInfo.focal_length.num = BACK_CAMERA_FOCAL_LENGTH;
+    else
+        mExifInfo.focal_length.num = FRONT_CAMERA_FOCAL_LENGTH;
+
+    mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN;
+    //3 User Comments
+    strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS);
+    //3 Color Space information
+    mExifInfo.color_space = EXIF_DEF_COLOR_SPACE;
+    //3 Exposure Mode
+    mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE;
+
+    //2 0th IFD GPS Info Tags
+    unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 };
+    memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version));
+
+    //2 1th IFD TIFF Tags
+    mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION;
+    mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM;
+    mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN;
+    mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM;
+    mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN;
+    mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT;
+}
+
+void SecCamera::setExifChangedAttribute()
+{
+    //2 0th IFD TIFF Tags
+    //3 Width
+    mExifInfo.width = m_snapshot_width;
+    //3 Height
+    mExifInfo.height = m_snapshot_height;
+    //3 Orientation
+    switch (m_exif_orientation) {
+    case 90:
+        mExifInfo.orientation = EXIF_ORIENTATION_90;
+        break;
+    case 180:
+        mExifInfo.orientation = EXIF_ORIENTATION_180;
+        break;
+    case 270:
+        mExifInfo.orientation = EXIF_ORIENTATION_270;
+        break;
+    case 0:
+    default:
+        mExifInfo.orientation = EXIF_ORIENTATION_UP;
+        break;
+    }
+    //3 Date time
+    time_t rawtime;
+    struct tm *timeinfo;
+    time(&rawtime);
+    timeinfo = localtime(&rawtime);
+    strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
+
+    //2 0th IFD Exif Private Tags
+    //3 Exposure Time
+    //int shutterSpeed = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd,  V4L2_CID_CAMERA_GET_SHT_TIME);
+    int shutterSpeed = 100;
+
+    /* TBD - front camera needs to be fixed to support this g_ctrl,
+       it current returns a negative err value, so avoid putting
+       odd value into exif for now */
+    if (shutterSpeed < 0) {
+        LOGE("%s: error %d getting shutterSpeed, camera_id = %d, using 100",
+             __func__, shutterSpeed, m_camera_id);
+        shutterSpeed = 100;
+    }
+    mExifInfo.exposure_time.num = 1;
+    // x us -> 1/x s */
+    mExifInfo.exposure_time.den = (uint32_t)(1000000 / shutterSpeed);
+
+    //3 ISO Speed Rating
+    int iso = m_params->iso;
+    //int iso = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_GET_ISO);
+    /* TBD - front camera needs to be fixed to support this g_ctrl,
+       it current returns a negative err value, so avoid putting
+       odd value into exif for now */
+    if (iso < 0) {
+        LOGE("%s: error %d getting iso, camera_id = %d, using 100",
+             __func__, iso, m_camera_id);
+        iso = ISO_100;
+    }
+    switch(iso) {
+    case ISO_50:
+        mExifInfo.iso_speed_rating = 50;
+        break;
+    case ISO_100:
+        mExifInfo.iso_speed_rating = 100;
+        break;
+    case ISO_200:
+        mExifInfo.iso_speed_rating = 200;
+        break;
+    case ISO_400:
+        mExifInfo.iso_speed_rating = 400;
+        break;
+    case ISO_800:
+        mExifInfo.iso_speed_rating = 800;
+        break;
+    case ISO_1600:
+        mExifInfo.iso_speed_rating = 1600;
+        break;
+    default:
+        mExifInfo.iso_speed_rating = 100;
+        break;
+    }
+
+    uint32_t av, tv, bv, sv, ev;
+    av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num / mExifInfo.fnumber.den);
+    tv = APEX_EXPOSURE_TO_SHUTTER((double)mExifInfo.exposure_time.num / mExifInfo.exposure_time.den);
+    sv = APEX_ISO_TO_FILMSENSITIVITY(mExifInfo.iso_speed_rating);
+    bv = av + tv - sv;
+    ev = av + tv;
+    LOGD("Shutter speed=%d us, iso=%d", shutterSpeed, mExifInfo.iso_speed_rating);
+    LOGD("AV=%d, TV=%d, SV=%d", av, tv, sv);
+
+    //3 Shutter Speed
+    mExifInfo.shutter_speed.num = tv*EXIF_DEF_APEX_DEN;
+    mExifInfo.shutter_speed.den = EXIF_DEF_APEX_DEN;
+    //3 Brightness
+    mExifInfo.brightness.num = bv*EXIF_DEF_APEX_DEN;
+    mExifInfo.brightness.den = EXIF_DEF_APEX_DEN;
+    //3 Exposure Bias
+    if (m_params->scene_mode == SCENE_MODE_BEACH_SNOW) {
+        mExifInfo.exposure_bias.num = EXIF_DEF_APEX_DEN;
+        mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN;
+    } else {
+        mExifInfo.exposure_bias.num = 0;
+        mExifInfo.exposure_bias.den = 0;
+    }
+    //3 Metering Mode
+    switch (m_params->metering) {
+    case METERING_SPOT:
+        mExifInfo.metering_mode = EXIF_METERING_SPOT;
+        break;
+    case METERING_MATRIX:
+        mExifInfo.metering_mode = EXIF_METERING_AVERAGE;
+        break;
+    case METERING_CENTER:
+        mExifInfo.metering_mode = EXIF_METERING_CENTER;
+        break;
+    default :
+        mExifInfo.metering_mode = EXIF_METERING_AVERAGE;
+        break;
+    }
+
+    //3 Flash
+    int flash = m_params->flash_mode;
+    //int flash = v4l2_gsc_cap_g_ctrl(m_gsc_vd_fd, V4L2_CID_CAMERA_GET_FLASH_ONOFF);
+    if (flash < 0)
+        mExifInfo.flash = EXIF_DEF_FLASH;
+    else
+        mExifInfo.flash = flash;
+
+    //3 White Balance
+    if (m_params->white_balance == WHITE_BALANCE_AUTO)
+        mExifInfo.white_balance = EXIF_WB_AUTO;
+    else
+        mExifInfo.white_balance = EXIF_WB_MANUAL;
+    //3 Scene Capture Type
+    switch (m_params->scene_mode) {
+    case SCENE_MODE_PORTRAIT:
+        mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT;
+        break;
+    case SCENE_MODE_LANDSCAPE:
+        mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE;
+        break;
+    case SCENE_MODE_NIGHTSHOT:
+        mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT;
+        break;
+    default:
+        mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD;
+        break;
+    }
+
+    //2 0th IFD GPS Info Tags
+    if (m_gps_latitude != 0 && m_gps_longitude != 0) {
+        if (m_gps_latitude > 0)
+            strcpy((char *)mExifInfo.gps_latitude_ref, "N");
+        else
+            strcpy((char *)mExifInfo.gps_latitude_ref, "S");
+
+        if (m_gps_longitude > 0)
+            strcpy((char *)mExifInfo.gps_longitude_ref, "E");
+        else
+            strcpy((char *)mExifInfo.gps_longitude_ref, "W");
+
+        if (m_gps_altitude > 0)
+            mExifInfo.gps_altitude_ref = 0;
+        else
+            mExifInfo.gps_altitude_ref = 1;
+
+        double latitude = fabs(m_gps_latitude / 10000.0);
+        double longitude = fabs(m_gps_longitude / 10000.0);
+        double altitude = fabs(m_gps_altitude / 100.0);
+
+        mExifInfo.gps_latitude[0].num = (uint32_t)latitude;
+        mExifInfo.gps_latitude[0].den = 1;
+        mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60);
+        mExifInfo.gps_latitude[1].den = 1;
+        mExifInfo.gps_latitude[2].num = (uint32_t)((((latitude - mExifInfo.gps_latitude[0].num) * 60)
+                                        - mExifInfo.gps_latitude[1].num) * 60);
+        mExifInfo.gps_latitude[2].den = 1;
+
+        mExifInfo.gps_longitude[0].num = (uint32_t)longitude;
+        mExifInfo.gps_longitude[0].den = 1;
+        mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60);
+        mExifInfo.gps_longitude[1].den = 1;
+        mExifInfo.gps_longitude[2].num = (uint32_t)((((longitude - mExifInfo.gps_longitude[0].num) * 60)
+                                        - mExifInfo.gps_longitude[1].num) * 60);
+        mExifInfo.gps_longitude[2].den = 1;
+
+        mExifInfo.gps_altitude.num = (uint32_t)altitude;
+        mExifInfo.gps_altitude.den = 1;
+
+        struct tm tm_data;
+        gmtime_r(&m_gps_timestamp, &tm_data);
+        mExifInfo.gps_timestamp[0].num = tm_data.tm_hour;
+        mExifInfo.gps_timestamp[0].den = 1;
+        mExifInfo.gps_timestamp[1].num = tm_data.tm_min;
+        mExifInfo.gps_timestamp[1].den = 1;
+        mExifInfo.gps_timestamp[2].num = tm_data.tm_sec;
+        mExifInfo.gps_timestamp[2].den = 1;
+        snprintf((char*)mExifInfo.gps_datestamp, sizeof(mExifInfo.gps_datestamp),
+                "%04d:%02d:%02d", tm_data.tm_year + 1900, tm_data.tm_mon + 1, tm_data.tm_mday);
+
+        mExifInfo.enableGps = true;
+    } else {
+        mExifInfo.enableGps = false;
+    }
+
+    //2 1th IFD TIFF Tags
+    mExifInfo.widthThumb = m_jpeg_thumbnail_width;
+    mExifInfo.heightThumb = m_jpeg_thumbnail_height;
+}
+
+int SecCamera::makeExif (unsigned char *exifOut,
+                                        unsigned char *thumb_buf,
+                                        unsigned int thumb_size,
+                                        exif_attribute_t *exifInfo,
+                                        unsigned int *size,
+                                        bool useMainbufForThumb)
+{
+    unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset;
+    unsigned int tmp, LongerTagOffest = 0;
+    pApp1Start = pCur = exifOut;
+
+    //2 Exif Identifier Code & TIFF Header
+    pCur += 4;  // Skip 4 Byte for APP1 marker and length
+    unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
+    memcpy(pCur, ExifIdentifierCode, 6);
+    pCur += 6;
+
+    /* Byte Order - little endian, Offset of IFD - 0x00000008.H */
+    unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
+    memcpy(pCur, TiffHeader, 8);
+    pIfdStart = pCur;
+    pCur += 8;
+
+    //2 0th IFD TIFF Tags
+    if (exifInfo->enableGps)
+        tmp = NUM_0TH_IFD_TIFF;
+    else
+        tmp = NUM_0TH_IFD_TIFF - 1;
+
+    memcpy(pCur, &tmp, NUM_SIZE);
+    pCur += NUM_SIZE;
+
+    LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
+
+    writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
+                 1, exifInfo->width);
+    writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
+                 1, exifInfo->height);
+    writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII,
+                 strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII,
+                 strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
+                 1, exifInfo->orientation);
+    writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
+                 strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII,
+                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT,
+                 1, exifInfo->ycbcr_positioning);
+    writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG,
+                 1, LongerTagOffest);
+    if (exifInfo->enableGps) {
+        pGpsIfdPtr = pCur;
+        pCur += IFD_SIZE;   // Skip a ifd size for gps IFD pointer
+    }
+
+    pNextIfdOffset = pCur;  // Skip a offset size for next IFD offset
+    pCur += OFFSET_SIZE;
+
+    //2 0th IFD Exif Private Tags
+    pCur = pIfdStart + LongerTagOffest;
+
+    tmp = NUM_0TH_IFD_EXIF;
+    memcpy(pCur, &tmp , NUM_SIZE);
+    pCur += NUM_SIZE;
+
+    LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE;
+
+    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL,
+                 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL,
+                 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT,
+                 1, exifInfo->exposure_program);
+    writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT,
+                 1, exifInfo->iso_speed_rating);
+    writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED,
+                 4, exifInfo->exif_version);
+    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII,
+                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII,
+                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL,
+                 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL,
+                 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL,
+                 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL,
+                 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL,
+                 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT,
+                 1, exifInfo->metering_mode);
+    writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT,
+                 1, exifInfo->flash);
+    writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL,
+                 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart);
+    char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 };
+    int commentsLen = strlen((char *)exifInfo->user_comment) + 1;
+    memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen);
+    memcpy(exifInfo->user_comment, code, sizeof(code));
+    writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED,
+                 commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart);
+    writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT,
+                 1, exifInfo->color_space);
+    writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG,
+                 1, exifInfo->width);
+    writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG,
+                 1, exifInfo->height);
+    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG,
+                 1, exifInfo->exposure_mode);
+    writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG,
+                 1, exifInfo->white_balance);
+    writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG,
+                 1, exifInfo->scene_capture_type);
+    tmp = 0;
+    memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
+    pCur += OFFSET_SIZE;
+
+    //2 0th IFD GPS Info Tags
+    if (exifInfo->enableGps) {
+        writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG,
+                     1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD
+
+        pCur = pIfdStart + LongerTagOffest;
+
+        if (exifInfo->gps_processing_method[0] == 0) {
+            // don't create GPS_PROCESSING_METHOD tag if there isn't any
+            tmp = NUM_0TH_IFD_GPS - 1;
+        } else {
+            tmp = NUM_0TH_IFD_GPS;
+        }
+        memcpy(pCur, &tmp, NUM_SIZE);
+        pCur += NUM_SIZE;
+
+        LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
+
+        writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE,
+                     4, exifInfo->gps_version_id);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII,
+                     2, exifInfo->gps_latitude_ref);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL,
+                     3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII,
+                     2, exifInfo->gps_longitude_ref);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL,
+                     3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE,
+                     1, exifInfo->gps_altitude_ref);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL,
+                     1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart);
+        writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL,
+                     3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart);
+        tmp = strlen((char*)exifInfo->gps_processing_method);
+        if (tmp > 0) {
+            if (tmp > 100) {
+                tmp = 100;
+            }
+            static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
+            unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)];
+            memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
+            memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp);
+            writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED,
+                         tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart);
+        }
+        writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII,
+                     11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart);
+        tmp = 0;
+        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
+        pCur += OFFSET_SIZE;
+    }
+
+    //2 1th IFD TIFF Tags
+
+    unsigned char *thumbBuf = thumb_buf;
+    unsigned int thumbSize = thumb_size;
+
+    if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize > 0)) {
+        tmp = LongerTagOffest;
+        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
+
+        pCur = pIfdStart + LongerTagOffest;
+
+        tmp = NUM_1TH_IFD_TIFF;
+        memcpy(pCur, &tmp, NUM_SIZE);
+        pCur += NUM_SIZE;
+
+        LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE;
+
+        writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
+                     1, exifInfo->widthThumb);
+        writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
+                     1, exifInfo->heightThumb);
+        writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT,
+                     1, exifInfo->compression_scheme);
+        writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
+                     1, exifInfo->orientation);
+        writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL,
+                     1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart);
+        writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL,
+                     1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart);
+        writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT,
+                     1, exifInfo->resolution_unit);
+        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG,
+                     1, LongerTagOffest);
+        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG,
+                     1, thumbSize);
+
+        tmp = 0;
+        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
+        pCur += OFFSET_SIZE;
+
+        memcpy(pIfdStart + LongerTagOffest, thumbBuf, thumbSize);
+        LongerTagOffest += thumbSize;
+    } else {
+        tmp = 0;
+        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
+    }
+
+    unsigned char App1Marker[2] = { 0xff, 0xe1 };
+    memcpy(pApp1Start, App1Marker, 2);
+    pApp1Start += 2;
+
+    *size = 10 + LongerTagOffest;
+    tmp = *size - 2;    // APP1 Maker isn't counted
+    unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF};
+    memcpy(pApp1Start, size_mm, 2);
+
+    LOGD("makeExif X");
+
+    return 0;
+}
+
+inline void SecCamera::writeExifIfd(unsigned char **pCur,
+                                         unsigned short tag,
+                                         unsigned short type,
+                                         unsigned int count,
+                                         uint32_t value)
+{
+    memcpy(*pCur, &tag, 2);
+    *pCur += 2;
+    memcpy(*pCur, &type, 2);
+    *pCur += 2;
+    memcpy(*pCur, &count, 4);
+    *pCur += 4;
+    memcpy(*pCur, &value, 4);
+    *pCur += 4;
+}
+
+inline void SecCamera::writeExifIfd(unsigned char **pCur,
+                                         unsigned short tag,
+                                         unsigned short type,
+                                         unsigned int count,
+                                         unsigned char *pValue)
+{
+    char buf[4] = { 0,};
+
+    memcpy(buf, pValue, count);
+    memcpy(*pCur, &tag, 2);
+    *pCur += 2;
+    memcpy(*pCur, &type, 2);
+    *pCur += 2;
+    memcpy(*pCur, &count, 4);
+    *pCur += 4;
+    memcpy(*pCur, buf, 4);
+    *pCur += 4;
+}
+
+inline void SecCamera::writeExifIfd(unsigned char **pCur,
+                                         unsigned short tag,
+                                         unsigned short type,
+                                         unsigned int count,
+                                         unsigned char *pValue,
+                                         unsigned int *offset,
+                                         unsigned char *start)
+{
+    memcpy(*pCur, &tag, 2);
+    *pCur += 2;
+    memcpy(*pCur, &type, 2);
+    *pCur += 2;
+    memcpy(*pCur, &count, 4);
+    *pCur += 4;
+    memcpy(*pCur, offset, 4);
+    *pCur += 4;
+    memcpy(start + *offset, pValue, count);
+    *offset += count;
+}
+
+inline void SecCamera::writeExifIfd(unsigned char **pCur,
+                                         unsigned short tag,
+                                         unsigned short type,
+                                         unsigned int count,
+                                         rational_t *pValue,
+                                         unsigned int *offset,
+                                         unsigned char *start)
+{
+    memcpy(*pCur, &tag, 2);
+    *pCur += 2;
+    memcpy(*pCur, &type, 2);
+    *pCur += 2;
+    memcpy(*pCur, &count, 4);
+    *pCur += 4;
+    memcpy(*pCur, offset, 4);
+    *pCur += 4;
+    memcpy(start + *offset, pValue, 8 * count);
+    *offset += 8 * count;
+}
+
+status_t SecCamera::dump(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    snprintf(buffer, 255, "dump(%d)\n", fd);
+    result.append(buffer);
+    ::write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+double SecCamera::jpeg_ratio = 0.7;
+int SecCamera::interleaveDataSize = 5242880;
+int SecCamera::jpegLineLength = 636;
+
+}; // namespace android
diff --git a/exynos5/hal/libcamera/SecCamera.h b/exynos5/hal/libcamera/SecCamera.h
new file mode 100644
index 0000000..1af19ee
--- /dev/null
+++ b/exynos5/hal/libcamera/SecCamera.h
@@ -0,0 +1,698 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+** Copyright 2010, Samsung Electronics Co. LTD
+**
+** 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 ANDROID_HARDWARE_CAMERA_SEC_H
+#define ANDROID_HARDWARE_CAMERA_SEC_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <videodev2.h>
+#include <videodev2_samsung.h>
+#include <linux/vt.h>
+
+#include <media.h>
+#include <v4l2-mediabus.h>
+#include <v4l2-subdev.h>
+
+#include <sec_utils_v4l2.h>
+
+#include "SecBuffer.h"
+
+#include <mediactl.h>
+#include <v4l2subdev.h>
+
+#include <utils/String8.h>
+
+#include "SecJpegEncoder.h"
+
+#include "Exif.h"
+namespace android {
+
+//#define ENABLE_ESD_PREVIEW_CHECK
+
+#if defined(LOG_NDEBUG) && (LOG_NDEBUG == 0)
+#define LOG_CAMERA LOGD
+#define LOG_CAMERA_PREVIEW LOGD
+
+#define LOG_TIME_DEFINE(n) \
+    struct timeval time_start_##n, time_stop_##n; unsigned long log_time_##n = 0;
+
+#define LOG_TIME_START(n) \
+    gettimeofday(&time_start_##n, NULL);
+
+#define LOG_TIME_END(n) \
+    gettimeofday(&time_stop_##n, NULL); log_time_##n = measure_time_camera(&time_start_##n, &time_stop_##n);
+
+#define LOG_TIME(n) \
+    log_time_##n
+
+#else
+#define LOG_CAMERA(...)
+#define LOG_CAMERA_PREVIEW(...)
+#define LOG_TIME_DEFINE(n)
+#define LOG_TIME_START(n)
+#define LOG_TIME_END(n)
+#define LOG_TIME(n)
+#endif
+
+#define JOIN(x, y) JOIN_AGAIN(x, y)
+#define JOIN_AGAIN(x, y) x ## y
+
+#define FRONT_CAM M5MO
+#define BACK_CAM S5K4E5
+
+#if !defined (FRONT_CAM) || !defined(BACK_CAM)
+#error "Please define the Camera module"
+#endif
+
+#define M5MO_PREVIEW_WIDTH                  1920
+#define M5MO_PREVIEW_HEIGHT                 1080
+#define M5MO_SNAPSHOT_WIDTH                 3264
+#define M5MO_SNAPSHOT_HEIGHT                2448
+
+#define M5MO_THUMBNAIL_WIDTH                320
+#define M5MO_THUMBNAIL_HEIGHT               240
+#define M5MO_THUMBNAIL_BPP                  16
+
+#define M5MO_FPS                            30
+
+/* focal length of 3.43mm */
+#define M5MO_FOCAL_LENGTH                   343
+
+#define S5K4E5_PREVIEW_WIDTH                1920
+#define S5K4E5_PREVIEW_HEIGHT               1080
+#define S5K4E5_SNAPSHOT_WIDTH               1920
+#define S5K4E5_SNAPSHOT_HEIGHT              1080
+
+#define S5K4E5_THUMBNAIL_WIDTH              320
+#define S5K4E5_THUMBNAIL_HEIGHT             240
+#define S5K4E5_THUMBNAIL_BPP                16
+
+#define S5K4E5_FPS                          30
+
+/* focal length of 0.9mm */
+#define S5K4E5_FOCAL_LENGTH                 90
+
+#define MAX_BACK_CAMERA_PREVIEW_WIDTH       JOIN(BACK_CAM,_PREVIEW_WIDTH)
+#define MAX_BACK_CAMERA_PREVIEW_HEIGHT      JOIN(BACK_CAM,_PREVIEW_HEIGHT)
+#define MAX_BACK_CAMERA_SNAPSHOT_WIDTH      JOIN(BACK_CAM,_SNAPSHOT_WIDTH)
+#define MAX_BACK_CAMERA_SNAPSHOT_HEIGHT     JOIN(BACK_CAM,_SNAPSHOT_HEIGHT)
+
+#define BACK_CAMERA_THUMBNAIL_WIDTH         JOIN(BACK_CAM,_THUMBNAIL_WIDTH)
+#define BACK_CAMERA_THUMBNAIL_HEIGHT        JOIN(BACK_CAM,_THUMBNAIL_HEIGHT)
+#define BACK_CAMERA_THUMBNAIL_BPP           JOIN(BACK_CAM,_THUMBNAIL_BPP)
+
+#define BACK_CAMERA_FPS                     JOIN(BACK_CAM,_FPS)
+
+#define BACK_CAMERA_FOCAL_LENGTH            JOIN(BACK_CAM,_FOCAL_LENGTH)
+
+#define MAX_FRONT_CAMERA_PREVIEW_WIDTH      JOIN(FRONT_CAM,_PREVIEW_WIDTH)
+#define MAX_FRONT_CAMERA_PREVIEW_HEIGHT     JOIN(FRONT_CAM,_PREVIEW_HEIGHT)
+#define MAX_FRONT_CAMERA_SNAPSHOT_WIDTH     JOIN(FRONT_CAM,_SNAPSHOT_WIDTH)
+#define MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT    JOIN(FRONT_CAM,_SNAPSHOT_HEIGHT)
+
+#define FRONT_CAMERA_THUMBNAIL_WIDTH        JOIN(FRONT_CAM,_THUMBNAIL_WIDTH)
+#define FRONT_CAMERA_THUMBNAIL_HEIGHT       JOIN(FRONT_CAM,_THUMBNAIL_HEIGHT)
+#define FRONT_CAMERA_THUMBNAIL_BPP          JOIN(FRONT_CAM,_THUMBNAIL_BPP)
+
+#define FRONT_CAMERA_FPS                    JOIN(FRONT_CAM,_FPS)
+
+#define FRONT_CAMERA_FOCAL_LENGTH           JOIN(FRONT_CAM,_FOCAL_LENGTH)
+
+#define DEFAULT_JPEG_THUMBNAIL_WIDTH        256
+#define DEFAULT_JPEG_THUMBNAIL_HEIGHT       192
+
+#define PFX_NODE_GSC                        "/dev/video"
+
+#define M5MOLS_ENTITY_NAME                  "M5MOLS 5-001f"
+#define PFX_SUBDEV_ENTITY_MIPI_CSIS         "s5p-mipi-csis"
+#define PFX_SUBDEV_ENTITY_FLITE             "exynos-fimc-lite"
+#define PFX_SUBDEV_ENTITY_GSC_CAP           "gsc-cap-subdev"
+#define PFX_VIDEODEV_ENTITY_GSC_CAP         "exynos-gsc"
+#define FIMD1_ENTITY_NAME                   "s5p-fimd1"
+
+#define GAIA_FW_BETA                        1
+
+#ifndef GAIA_FW_BETA
+#define GSC_VD_NODE_OFFSET                  25         //GSCALER 0 (0:25, 1:28, 2:31, 3:34)
+#else
+#define GSC_VD_NODE_OFFSET                  41         //INTERNAL_ISP 4E5
+
+#define ISP_SENSOR_MAX_ENTITIES             1
+#define ISP_SENSOR_PAD_SOURCE_FRONT         0
+#define ISP_SENSOR_PADS_NUM                 1
+
+#define ISP_FRONT_MAX_ENTITIES              1
+#define ISP_FRONT_PAD_SINK                  0
+#define ISP_FRONT_PAD_SOURCE_BACK           1
+#define ISP_FRONT_PAD_SOURCE_BAYER          2
+#define ISP_FRONT_PAD_SOURCE_SCALERC        3
+#define ISP_FRONT_PADS_NUM                  4
+
+#define ISP_BACK_MAX_ENTITIES               1
+#define ISP_BACK_PAD_SINK                   0
+#define ISP_BACK_PAD_SOURCE_3DNR            1
+#define ISP_BACK_PAD_SOURCE_SCALERP         2
+#define ISP_BACK_PADS_NUM                   3
+
+#define ISP_MODULE_NAME                     "exynos5-fimc-is"
+#define ISP_SENSOR_ENTITY_NAME              "exynos5-fimc-is-sensor"
+#define ISP_FRONT_ENTITY_NAME               "exynos5-fimc-is-front"
+#define ISP_BACK_ENTITY_NAME                "exynos5-fimc-is-back"
+#define ISP_VIDEO_BAYER_NAME                "exynos5-fimc-is-bayer"
+#define ISP_VIDEO_SCALERC_NAME              "exynos5-fimc-is-scalerc"
+#define ISP_VIDEO_3DNR_NAME                 "exynos5-fimc-is-3dnr"
+#define ISP_VIDEO_SCALERP_NAME              "exynos5-fimc-is-scalerp"
+
+#endif
+#define MIPI_NUM                            1
+#define FLITE_NUM                           1
+#define GSC_NUM                             0
+
+#define PFX_SUBDEV_NODE                     "/dev/v4l-subdev"
+
+#define BPP             2
+#define MIN(x, y)       (((x) < (y)) ? (x) : (y))
+#ifndef GAIA_FW_BETA
+#define MAX_BUFFERS     8
+#else
+#define MAX_BUFFERS     4  //external : 8,  internal : 4
+#endif
+
+#define MAX_PLANES      (3)
+#define V4L2_BUF_TYPE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
+
+#define V4L2_MEMORY_TYPE V4L2_MEMORY_USERPTR
+#define RECORD_PIX_FMT V4L2_PIX_FMT_NV12M
+#define PREVIEW_NUM_PLANE (3)
+#define RECORD_NUM_PLANE (2)
+
+/*
+ * V 4 L 2   F I M C   E X T E N S I O N S
+ *
+ */
+#define V4L2_CID_ROTATION                   (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_PADDR_Y                    (V4L2_CID_PRIVATE_BASE + 1)
+#define V4L2_CID_PADDR_CB                   (V4L2_CID_PRIVATE_BASE + 2)
+#define V4L2_CID_PADDR_CR                   (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_PADDR_CBCR                 (V4L2_CID_PRIVATE_BASE + 4)
+#define V4L2_CID_STREAM_PAUSE               (V4L2_CID_PRIVATE_BASE + 53)
+
+#define V4L2_CID_CAM_JPEG_MAIN_SIZE         (V4L2_CID_PRIVATE_BASE + 32)
+#define V4L2_CID_CAM_JPEG_MAIN_OFFSET       (V4L2_CID_PRIVATE_BASE + 33)
+#define V4L2_CID_CAM_JPEG_THUMB_SIZE        (V4L2_CID_PRIVATE_BASE + 34)
+#define V4L2_CID_CAM_JPEG_THUMB_OFFSET      (V4L2_CID_PRIVATE_BASE + 35)
+#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET   (V4L2_CID_PRIVATE_BASE + 36)
+#define V4L2_CID_CAM_JPEG_QUALITY           (V4L2_CID_PRIVATE_BASE + 37)
+
+#define TPATTERN_COLORBAR           1
+#define TPATTERN_HORIZONTAL         2
+#define TPATTERN_VERTICAL           3
+
+#define V4L2_PIX_FMT_YVYU           v4l2_fourcc('Y', 'V', 'Y', 'U')
+
+/* FOURCC for FIMC specific */
+#define V4L2_PIX_FMT_VYUY           v4l2_fourcc('V', 'Y', 'U', 'Y')
+#define V4L2_PIX_FMT_NV16           v4l2_fourcc('N', 'V', '1', '6')
+#define V4L2_PIX_FMT_NV61           v4l2_fourcc('N', 'V', '6', '1')
+#define V4L2_PIX_FMT_NV12T          v4l2_fourcc('T', 'V', '1', '2')
+/*
+ * U S E R   D E F I N E D   T Y P E S
+ *
+ */
+#define PREVIEW_MODE 1
+#define RECORD_MODE 2
+
+/* We use this struct as the v4l2_streamparm raw_data for
+ * VIDIOC_G_PARM and VIDIOC_S_PARM
+ */
+struct sec_cam_parm {
+    struct v4l2_captureparm capture;
+    int contrast;
+    int effects;
+    int brightness;
+    int exposure;
+    int flash_mode;
+    int focus_mode;
+    int iso;
+    int metering;
+    int saturation;
+    int scene_mode;
+    int sharpness;
+    int hue;
+    int white_balance;
+};
+
+struct yuv_fmt_list {
+    const char  *name;
+    const char  *desc;
+    unsigned int    fmt;
+    int     depth;
+    int     planes;
+};
+
+struct camsensor_date_info {
+    unsigned int year;
+    unsigned int month;
+    unsigned int date;
+};
+
+class SecCamera : public virtual RefBase {
+public:
+
+    enum CAMERA_ID {
+        CAMERA_ID_BACK  = 0,
+        CAMERA_ID_FRONT = 1,
+    };
+
+    enum JPEG_QUALITY {
+        JPEG_QUALITY_ECONOMY    = 0,
+        JPEG_QUALITY_NORMAL     = 50,
+        JPEG_QUALITY_SUPERFINE  = 100,
+        JPEG_QUALITY_MAX,
+    };
+
+    enum OBJECT_TRACKING {
+        OBJECT_TRACKING_OFF,
+        OBJECT_TRACKING_ON,
+        OBJECT_TRACKING_MAX,
+    };
+
+    /*VT call*/
+    enum VT_MODE {
+        VT_MODE_OFF,
+        VT_MODE_ON,
+        VT_MODE_MAX,
+    };
+
+    /*Camera sensor mode - Camcorder fix fps*/
+    enum SENSOR_MODE {
+        SENSOR_MODE_CAMERA,
+        SENSOR_MODE_MOVIE,
+    };
+
+    /*Camera Shot mode*/
+    enum SHOT_MODE {
+        SHOT_MODE_SINGLE        = 0,
+        SHOT_MODE_CONTINUOUS    = 1,
+        SHOT_MODE_PANORAMA      = 2,
+        SHOT_MODE_SMILE         = 3,
+        SHOT_MODE_SELF          = 6,
+    };
+
+    enum CHK_DATALINE {
+        CHK_DATALINE_OFF,
+        CHK_DATALINE_ON,
+        CHK_DATALINE_MAX,
+    };
+
+    int m_touch_af_start_stop;
+
+    SecCamera();
+    virtual ~SecCamera();
+
+    static SecCamera* createInstance(void)
+    {
+        static SecCamera singleton;
+        return &singleton;
+    }
+    status_t dump(int fd);
+
+    bool            CreateCamera(int index);
+    bool            DestroyCamera(void);
+    int             getCameraId(void);
+
+    int             startPreview(void);
+    int             stopPreview(void);
+    int             getPreviewState(void)
+    {
+        return m_preview_state;
+    }
+    void            clearPreviewState(void)
+    {
+        m_preview_state = 0;
+    }
+
+    int             startRecord(void);
+    int             stopRecord(void);
+    int             setPreviewFrame(int index);
+    int             getRecordFrame(void);
+    int             releaseRecordFrame(int index);
+    int             getRecordAddr(int index, SecBuffer *buffer);
+
+    int             getPreview(void);
+    int             setPreviewSize(int width, int height, int pixel_format);
+    int             getPreviewSize(int *width, int *height, int *frame_size);
+    int             getPreviewMaxSize(int *width, int *height);
+    int             getPreviewPixelFormat(void);
+    int             setPreviewImage(int index, unsigned char *buffer, int size);
+
+    int             setSnapshotSize(int width, int height);
+    int             getSnapshotSize(int *width, int *height, int *frame_size);
+    int             getSnapshotMaxSize(int *width, int *height);
+    int             setSnapshotPixelFormat(int pixel_format);
+    int             getSnapshotPixelFormat(void);
+
+    unsigned char*  getJpeg(unsigned char *snapshot_data, int snapshot_size, int *size);
+    unsigned char*  yuv2Jpeg(unsigned char *raw_data, int raw_size,
+                                int *jpeg_size,
+                                int width, int height, int pixel_format);
+
+    int             setJpegThumbnailSize(int width, int height);
+    int             getJpegThumbnailSize(int *width, int *height);
+
+    int             setJpegThumbnailQuality(int jpeg_thumbnail_quality);
+    int             getJpegThumbnailQuality(void);
+
+    int             setAutofocus(void);
+
+    int             SetRotate(int angle);
+    int             getRotate(void);
+
+    int             setVerticalMirror(void);
+    int             setHorizontalMirror(void);
+
+    int             setWhiteBalance(int white_balance);
+    int             getWhiteBalance(void);
+
+    int             setBrightness(int brightness);
+    int             getBrightness(void);
+
+    int             setExposure(int exposure);
+    int             getExposure(void);
+
+    int             setImageEffect(int image_effect);
+    int             getImageEffect(void);
+
+    int             setSceneMode(int scene_mode);
+    int             getSceneMode(void);
+
+    int             setFlashMode(int flash_mode);
+    int             getFlashMode(void);
+
+    int             setMetering(int metering_value);
+    int             getMetering(void);
+
+    int             setISO(int iso_value);
+    int             getISO(void);
+
+    int             setContrast(int contrast_value);
+    int             getContrast(void);
+
+    int             setSaturation(int saturation_value);
+    int             getSaturation(void);
+
+    int             setSharpness(int sharpness_value);
+    int             getSharpness(void);
+
+    int             setHue(int hue_value);
+    int             getHue(void);
+
+    int             setWDR(int wdr_value);
+    int             getWDR(void);
+
+    int             setAntiShake(int anti_shake);
+    int             getAntiShake(void);
+
+    int             setJpegQuality(int jpeg_qality);
+    int             getJpegQuality(void);
+
+    int             setZoom(int zoom_level);
+    int             getZoom(void);
+
+    int             setObjectTracking(int object_tracking);
+    int             getObjectTracking(void);
+    int             getObjectTrackingStatus(void);
+
+    int             setSmartAuto(int smart_auto);
+    int             getSmartAuto(void);
+    int             getAutosceneStatus(void);
+
+    int             setBeautyShot(int beauty_shot);
+    int             getBeautyShot(void);
+
+    int             setVintageMode(int vintage_mode);
+    int             getVintageMode(void);
+
+    int             setFocusMode(int focus_mode);
+    int             getFocusMode(void);
+
+    int             setFaceDetect(int face_detect);
+    int             getFaceDetect(void);
+
+    int             setGPSLatitude(const char *gps_latitude);
+    int             setGPSLongitude(const char *gps_longitude);
+    int             setGPSAltitude(const char *gps_altitude);
+    int             setGPSTimeStamp(const char *gps_timestamp);
+    int             setGPSProcessingMethod(const char *gps_timestamp);
+    int             cancelAutofocus(void);
+    int             setFaceDetectLockUnlock(int facedetect_lockunlock);
+    int             setObjectPosition(int x, int y);
+    int             setObjectTrackingStartStop(int start_stop);
+    int             setTouchAFStartStop(int start_stop);
+    int             setCAFStatus(int on_off);
+    int             getAutoFocusResult(void);
+    int             setAntiBanding(int anti_banding);
+    int             getPostview(void);
+    int             setRecording(int recording_en);
+    int             setRecordingSize(int width, int height);
+    int             getRecordingSize(int *width, int *height);
+    int             setGamma(int gamma);
+    int             setSlowAE(int slow_ae);
+    int             setExifOrientationInfo(int orientationInfo);
+    int             setBatchReflection(void);
+    int             setSnapshotCmd(void);
+    int             endSnapshot(void);
+    int             setCameraSensorReset(void);
+    int             setSensorMode(int sensor_mode); /* Camcorder fix fps */
+    int             setShotMode(int shot_mode);     /* Shot mode */
+    int             setDataLineCheck(int chk_dataline);
+    int             getDataLineCheck(void);
+    int             setDataLineCheckStop(void);
+    int             setDefultIMEI(int imei);
+    int             getDefultIMEI(void);
+    const __u8*     getCameraSensorName(void);
+#ifdef ENABLE_ESD_PREVIEW_CHECK
+    int             getCameraSensorESDStatus(void);
+#endif // ENABLE_ESD_PREVIEW_CHECK
+
+    int setFrameRate(int frame_rate);
+    unsigned char*  getJpeg(int*, unsigned int*);
+    int             getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf,
+                                        unsigned int *output_size);
+    int             getExif(unsigned char *pExifDst, unsigned char *pThumbSrc);
+
+    void            getPostViewConfig(int*, int*, int*);
+    void            getThumbnailConfig(int *width, int *height, int *size);
+
+    int             getPostViewOffset(void);
+    int             getCameraFd(void);
+    unsigned char*  getPictureVaddr(void);
+    int             getJpegFd(void);
+    void            SetJpgAddr(unsigned char *addr);
+    int             getPreviewAddr(int index, SecBuffer *buffer);
+    void            setUserBufferAddr(void *ptr, int index, int mode);
+    static void     setJpegRatio(double ratio)
+    {
+        if((ratio < 0) || (ratio > 1))
+            return;
+
+        jpeg_ratio = ratio;
+    }
+
+    static double   getJpegRatio()
+    {
+        return jpeg_ratio;
+    }
+
+    static void     setInterleaveDataSize(int x)
+    {
+        interleaveDataSize = x;
+    }
+
+    static int      getInterleaveDataSize()
+    {
+        return interleaveDataSize;
+    }
+
+    static void     setJpegLineLength(int x)
+    {
+        jpegLineLength = x;
+    }
+
+    static int      getJpegLineLength()
+    {
+        return jpegLineLength;
+    }
+
+private:
+    v4l2_streamparm m_streamparm;
+    struct sec_cam_parm   *m_params;
+    int             m_flagCreate;
+    int             m_preview_state;
+    int             m_camera_id;
+
+    /* v4l2 sub-dev file description */
+    int             m_cam_sd_fd;
+    int             m_mipi_sd_fd;
+    int             m_flite_sd_fd;
+    int             m_gsc_sd_fd;
+    int             m_gsc_vd_fd;
+
+    /* media controller variable */
+    struct media_device *media;
+    struct media_link   *links;
+    struct media_pad    *pads;
+
+    struct media_entity *camera_sd_entity;
+    struct media_entity *mipi_sd_entity;
+    struct media_entity *flite_sd_entity;
+    struct media_entity *gsc_cap_sd_entity;
+    struct media_entity *gsc_cap_vd_entity;
+    struct media_entity *isp_sensor_entity;
+    struct media_entity *isp_front_entity;
+    struct media_entity *isp_back_entity;
+    struct media_entity *isp_scalerc_entity;
+    struct media_entity *isp_scalerp_entity;
+    struct media_entity *isp_3dnr_entity;
+
+    int             m_cam_fd;
+
+    int             m_cam_fd2;
+    struct pollfd   m_events_c2;
+    int             m_flag_record_start;
+
+    int             m_preview_v4lformat;
+    int             m_preview_width;
+    int             m_preview_height;
+    int             m_preview_max_width;
+    int             m_preview_max_height;
+
+    int             m_snapshot_v4lformat;
+    int             m_snapshot_width;
+    int             m_snapshot_height;
+    int             m_snapshot_max_width;
+    int             m_snapshot_max_height;
+    unsigned char*  m_picture_vaddr;
+
+    int             m_angle;
+    int             m_anti_banding;
+    int             m_wdr;
+    int             m_anti_shake;
+    int             m_zoom_level;
+    int             m_object_tracking;
+    int             m_smart_auto;
+    int             m_beauty_shot;
+    int             m_vintage_mode;
+    int             m_face_detect;
+    int             m_object_tracking_start_stop;
+    int             m_recording_en;
+    int             m_recording_width;
+    int             m_recording_height;
+    long            m_gps_latitude;
+    long            m_gps_longitude;
+    long            m_gps_altitude;
+    long            m_gps_timestamp;
+    int             m_sensor_mode; /*Camcorder fix fps */
+    int             m_shot_mode; /* Shot mode */
+    int             m_exif_orientation;
+    int             m_chk_dataline;
+    int             m_video_gamma;
+    int             m_slow_ae;
+    int             m_camera_af_flag;
+
+    int             m_flag_camera_start;
+
+    int             m_jpeg_fd;
+    int             m_jpeg_thumbnail_width;
+    int             m_jpeg_thumbnail_height;
+    int             m_jpeg_thumbnail_quality;
+    int             m_jpeg_quality;
+
+    int             m_postview_offset;
+
+#ifdef ENABLE_ESD_PREVIEW_CHECK
+    int             m_esd_check_count;
+#endif // ENABLE_ESD_PREVIEW_CHECK
+
+    exif_attribute_t mExifInfo;
+
+    struct SecBuffer m_capture_buf;
+    struct SecBuffer m_buffers_preview[MAX_BUFFERS];
+    struct SecBuffer m_buffers_record[MAX_BUFFERS];
+    struct pollfd   m_events_c;
+
+    inline void     writeExifIfd(unsigned char **pCur,
+                                 unsigned short tag,
+                                 unsigned short type,
+                                 unsigned int count,
+                                 uint32_t value);
+    inline void     writeExifIfd(unsigned char **pCur,
+                                 unsigned short tag,
+                                 unsigned short type,
+                                 unsigned int count,
+                                 unsigned char *pValue);
+    inline void     writeExifIfd(unsigned char **pCur,
+                                 unsigned short tag,
+                                 unsigned short type,
+                                 unsigned int count,
+                                 rational_t *pValue,
+                                 unsigned int *offset,
+                                 unsigned char *start);
+    inline void     writeExifIfd(unsigned char **pCur,
+                                 unsigned short tag,
+                                 unsigned short type,
+                                 unsigned int count,
+                                 unsigned char *pValue,
+                                 unsigned int *offset,
+                                 unsigned char *start);
+
+    void            setExifChangedAttribute();
+    void            setExifFixedAttribute();
+    int             makeExif (unsigned char *exifOut,
+                                        unsigned char *thumb_buf,
+                                        unsigned int thumb_size,
+                                        exif_attribute_t *exifInfo,
+                                        unsigned int *size,
+                                        bool useMainbufForThumb);
+    void            resetCamera();
+
+    static double   jpeg_ratio;
+    static int      interleaveDataSize;
+    static int      jpegLineLength;
+};
+
+extern unsigned long measure_time_camera(struct timeval *start, struct timeval *stop);
+
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_CAMERA_SEC_H
diff --git a/exynos5/hal/libcamera/SecCameraHWInterface.cpp b/exynos5/hal/libcamera/SecCameraHWInterface.cpp
new file mode 100644
index 0000000..8cfbccc
--- /dev/null
+++ b/exynos5/hal/libcamera/SecCameraHWInterface.cpp
@@ -0,0 +1,3043 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+** Copyright 2010, Samsung Electronics Co. LTD
+**
+** 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.
+*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CameraHardwareSec"
+#include <utils/Log.h>
+
+#include "SecCameraHWInterface.h"
+#include <utils/threads.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <camera/Camera.h>
+#include <media/stagefright/MetadataBufferType.h>
+
+#define VIDEO_COMMENT_MARKER_H          0xFFBE
+#define VIDEO_COMMENT_MARKER_L          0xFFBF
+#define VIDEO_COMMENT_MARKER_LENGTH     4
+#define JPEG_EOI_MARKER                 0xFFD9
+#define HIBYTE(x) (((x) >> 8) & 0xFF)
+#define LOBYTE(x) ((x) & 0xFF)
+#define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
+
+#define BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR       "0.10,1.20,Infinity"
+#define BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR      "0.10,0.20,Infinity"
+#define BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR   "0.10,1.20,Infinity"
+#define FRONT_CAMERA_FOCUS_DISTANCES_STR           "0.20,0.25,Infinity"
+//#define USE_EGL
+
+// This hack does two things:
+// -- it sets preview to NV21 (YUV420SP)
+// -- it sets gralloc to YV12
+//
+// The reason being: the samsung encoder understands only yuv420sp, and gralloc
+// does yv12 and rgb565.  So what we do is we break up the interleaved UV in
+// separate V and U planes, which makes preview look good, and enabled the
+// encoder as well.
+//
+// FIXME: Samsung needs to enable support for proper yv12 coming out of the
+//        camera, and to fix their video encoder to work with yv12.
+// FIXME: It also seems like either Samsung's YUV420SP (NV21) or img's YV12 has
+//        the color planes switched.  We need to figure which side is doing it
+//        wrong and have the respective party fix it.
+
+namespace android {
+
+struct addrs {
+    uint32_t type;  // make sure that this is 4 byte.
+    unsigned int addr_y;
+    unsigned int addr_cbcr;
+    unsigned int buf_index;
+    unsigned int reserved;
+};
+
+struct addrs_cap {
+    unsigned int addr_y;
+    unsigned int width;
+    unsigned int height;
+};
+
+static const int INITIAL_SKIP_FRAME = 3;
+static const int EFFECT_SKIP_FRAME = 1;
+
+gralloc_module_t const* CameraHardwareSec::mGrallocHal;
+
+CameraHardwareSec::CameraHardwareSec(int cameraId, camera_device_t *dev)
+        :
+          mCaptureInProgress(false),
+          mParameters(),
+          mFrameSizeDelta(0),
+          mCameraSensorName(NULL),
+          mSkipFrame(0),
+          mNotifyCb(0),
+          mDataCb(0),
+          mDataCbTimestamp(0),
+          mCallbackCookie(0),
+          mMsgEnabled(CAMERA_MSG_RAW_IMAGE),
+          mRecordRunning(false),
+          mPostViewWidth(0),
+          mPostViewHeight(0),
+          mPostViewSize(0),
+          mHalDevice(dev)
+{
+    LOGV("%s :", __func__);
+    int ret = 0;
+
+    mPreviewWindow = NULL;
+    mSecCamera = SecCamera::createInstance();
+
+    mRawHeap = NULL;
+    mPreviewHeap = NULL;
+    for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++)
+        mRecordHeap[i] = NULL;
+
+    if (!mGrallocHal) {
+        ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&mGrallocHal);
+        if (ret)
+            LOGE("ERR(%s):Fail on loading gralloc HAL", __func__);
+    }
+
+    ret = mSecCamera->CreateCamera(cameraId);
+    if (ret < 0) {
+        LOGE("ERR(%s):Fail on mSecCamera init", __func__);
+        mSecCamera->DestroyCamera();
+    }
+
+    initDefaultParameters(cameraId);
+
+    mExitAutoFocusThread = false;
+    mExitPreviewThread = false;
+    /* whether the PreviewThread is active in preview or stopped.  we
+     * create the thread but it is initially in stopped state.
+     */
+    mPreviewRunning = false;
+    mPreviewStartDeferred = false;
+    mPreviewThread = new PreviewThread(this);
+    mAutoFocusThread = new AutoFocusThread(this);
+    mPictureThread = new PictureThread(this);
+}
+
+int CameraHardwareSec::getCameraId() const
+{
+    return mSecCamera->getCameraId();
+}
+
+void CameraHardwareSec::initDefaultParameters(int cameraId)
+{
+    if (mSecCamera == NULL) {
+        LOGE("ERR(%s):mSecCamera object is NULL", __func__);
+        return;
+    }
+
+    CameraParameters p;
+    CameraParameters ip;
+
+#ifndef GAIA_FW_BETA
+    mCameraSensorName = mSecCamera->getCameraSensorName();
+    if (mCameraSensorName == NULL) {
+        LOGE("ERR(%s):mCameraSensorName is NULL", __func__);
+        return;
+    }
+    LOGV("CameraSensorName: %s", mCameraSensorName);
+    int Internal_is = !strncmp((const char*)mCameraSensorName, "ISP Camera", 10);
+#else
+    int Internal_is = 0;
+    //sprintf((char *)mCameraSensorName, "%s", "temp name");
+#endif
+    int preview_max_width   = 0;
+    int preview_max_height  = 0;
+    int snapshot_max_width  = 0;
+    int snapshot_max_height = 0;
+
+    if (cameraId == SecCamera::CAMERA_ID_BACK) {
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
+              "3264x2448,2576x1948,1920x1080,1280x720,800x480,720x480,640x480,320x240,528x432,176x144");
+        p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
+              "3264x2448,1920x1080,1280x720,800x480,720x480,640x480");
+        if (Internal_is)
+            p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
+                  "1920x1080,1280x720,640x480,176x144");
+    } else {
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
+              "1392x1392,1280x720,640x480,352x288,320x240,176x144");
+        p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
+              "1392x1392,1280x960,640x480");
+        if (Internal_is)
+            p.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
+                  "1280x720,640x480,176x144");
+    }
+
+    p.getSupportedPreviewSizes(mSupportedPreviewSizes);
+
+    // If these fail, then we are using an invalid cameraId and we'll leave the
+    // sizes at zero to catch the error.
+    if (mSecCamera->getPreviewMaxSize(&preview_max_width,
+                                      &preview_max_height) < 0)
+        LOGE("getPreviewMaxSize fail (%d / %d)",
+             preview_max_width, preview_max_height);
+    if (mSecCamera->getSnapshotMaxSize(&snapshot_max_width,
+                                       &snapshot_max_height) < 0)
+        LOGE("getSnapshotMaxSize fail (%d / %d)",
+             snapshot_max_width, snapshot_max_height);
+
+    p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420P); mFrameSizeDelta = 16;
+    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, CameraParameters::PIXEL_FORMAT_YUV420P);
+    p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420SP);
+    p.setPreviewSize(preview_max_width, preview_max_height);
+
+    p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
+    p.setPictureSize(snapshot_max_width, snapshot_max_height);
+    p.set(CameraParameters::KEY_JPEG_QUALITY, "100"); // maximum quality
+    p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
+          CameraParameters::PIXEL_FORMAT_JPEG);
+
+    p.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, "1280x720");
+
+    String8 parameterString;
+
+    if (cameraId == SecCamera::CAMERA_ID_BACK) {
+        parameterString = CameraParameters::FOCUS_MODE_AUTO;
+        parameterString.append(",");
+        parameterString.append(CameraParameters::FOCUS_MODE_INFINITY);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::FOCUS_MODE_MACRO);
+        p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+              parameterString.string());
+        p.set(CameraParameters::KEY_FOCUS_MODE,
+              CameraParameters::FOCUS_MODE_AUTO);
+        p.set(CameraParameters::KEY_FOCUS_DISTANCES,
+              BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR);
+        p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
+              "320x240,0x0");
+        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320");
+        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240");
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30");
+        p.setPreviewFrameRate(30);
+    } else {
+        parameterString = CameraParameters::FOCUS_MODE_FIXED;
+        p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
+              parameterString.string());
+        p.set(CameraParameters::KEY_FOCUS_MODE,
+              CameraParameters::FOCUS_MODE_FIXED);
+        p.set(CameraParameters::KEY_FOCUS_DISTANCES,
+              FRONT_CAMERA_FOCUS_DISTANCES_STR);
+        p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
+              "160x120,0x0");
+        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "160");
+        p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "120");
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, "7,15,30");
+        p.setPreviewFrameRate(30);
+    }
+
+    parameterString = CameraParameters::EFFECT_NONE;
+    parameterString.append(",");
+    parameterString.append(CameraParameters::EFFECT_MONO);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::EFFECT_NEGATIVE);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::EFFECT_SEPIA);
+    p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, parameterString.string());
+
+    if (cameraId == SecCamera::CAMERA_ID_BACK) {
+        parameterString = CameraParameters::FLASH_MODE_ON;
+        parameterString.append(",");
+        parameterString.append(CameraParameters::FLASH_MODE_OFF);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::FLASH_MODE_AUTO);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::FLASH_MODE_TORCH);
+        p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
+              parameterString.string());
+        p.set(CameraParameters::KEY_FLASH_MODE,
+              CameraParameters::FLASH_MODE_OFF);
+
+        parameterString = CameraParameters::SCENE_MODE_AUTO;
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_PORTRAIT);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_LANDSCAPE);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_BEACH);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_SNOW);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_FIREWORKS);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_SPORTS);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_PARTY);
+        parameterString.append(",");
+        parameterString.append(CameraParameters::SCENE_MODE_CANDLELIGHT);
+        p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
+              parameterString.string());
+        p.set(CameraParameters::KEY_SCENE_MODE,
+              CameraParameters::SCENE_MODE_AUTO);
+
+        /* we have two ranges, 4-30fps for night mode and
+         * 15-30fps for all others
+         */
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)");
+        p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "15000,30000");
+
+        p.set(CameraParameters::KEY_FOCAL_LENGTH, "3.43");
+    } else {
+        p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(7500,30000)");
+        p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "7500,30000");
+
+        p.set(CameraParameters::KEY_FOCAL_LENGTH, "0.9");
+    }
+
+    parameterString = CameraParameters::WHITE_BALANCE_AUTO;
+    parameterString.append(",");
+    parameterString.append(CameraParameters::WHITE_BALANCE_INCANDESCENT);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::WHITE_BALANCE_FLUORESCENT);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::WHITE_BALANCE_DAYLIGHT);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT);
+    p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
+          parameterString.string());
+
+    p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "100");
+
+    p.set(CameraParameters::KEY_ROTATION, 0);
+    p.set(CameraParameters::KEY_WHITE_BALANCE, CameraParameters::WHITE_BALANCE_AUTO);
+
+    p.set(CameraParameters::KEY_EFFECT, CameraParameters::EFFECT_NONE);
+
+    p.set("contrast", "auto");
+    p.set("iso", "auto");
+    p.set("metering", "center");
+    p.set("wdr", 0);
+
+    ip.set("chk_dataline", 0);
+    if (cameraId == SecCamera::CAMERA_ID_FRONT) {
+        ip.set("vtmode", 0);
+        ip.set("blur", 0);
+    }
+
+    p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "51.2");
+    p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "39.4");
+
+    p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
+    p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "2");
+    p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-2");
+    p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "1");
+
+    p.set("brightness", 0);
+    p.set("brightness-max", 2);
+    p.set("brightness-min", -2);
+
+    p.set("saturation", 0);
+    p.set("saturation-max", 2);
+    p.set("saturation-min", -2);
+
+    p.set("sharpness", 0);
+    p.set("sharpness-max", 2);
+    p.set("sharpness-min", -2);
+
+    p.set("hue", 0);
+    p.set("hue-max", 2);
+    p.set("hue-min", -2);
+
+    parameterString = CameraParameters::ANTIBANDING_AUTO;
+    parameterString.append(",");
+    parameterString.append(CameraParameters::ANTIBANDING_50HZ);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::ANTIBANDING_60HZ);
+    parameterString.append(",");
+    parameterString.append(CameraParameters::ANTIBANDING_OFF);
+    p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
+          parameterString.string());
+
+    p.set(CameraParameters::KEY_ANTIBANDING, CameraParameters::ANTIBANDING_OFF);
+
+    mParameters = p;
+    mInternalParameters = ip;
+
+    /* make sure mSecCamera has all the settings we do.  applications
+     * aren't required to call setParameters themselves (only if they
+     * want to change something.
+     */
+    setParameters(p);
+    if (cameraId == SecCamera::CAMERA_ID_BACK)
+        mSecCamera->setFrameRate(BACK_CAMERA_FPS);
+    else
+        mSecCamera->setFrameRate(FRONT_CAMERA_FPS);
+}
+
+CameraHardwareSec::~CameraHardwareSec()
+{
+    LOGV("%s", __func__);
+    mSecCamera->DestroyCamera();
+}
+
+status_t CameraHardwareSec::setPreviewWindow(preview_stream_ops *w)
+{
+    int min_bufs;
+
+    mPreviewWindow = w;
+    LOGV("%s: mPreviewWindow %p", __func__, mPreviewWindow);
+
+    if (!w) {
+        LOGE("preview window is NULL!");
+        return OK;
+    }
+
+    mPreviewLock.lock();
+
+    if (mPreviewRunning && !mPreviewStartDeferred) {
+        LOGI("stop preview (window change)");
+        stopPreviewInternal();
+    }
+
+    if (w->get_min_undequeued_buffer_count(w, &min_bufs)) {
+        LOGE("%s: could not retrieve min undequeued buffer count", __func__);
+        return INVALID_OPERATION;
+    }
+
+    if (min_bufs >= BUFFER_COUNT_FOR_GRALLOC) {
+        LOGE("%s: min undequeued buffer count %d is too high (expecting at most %d)", __func__,
+             min_bufs, BUFFER_COUNT_FOR_GRALLOC - 1);
+    }
+
+    LOGV("%s: setting buffer count to %d", __func__, BUFFER_COUNT_FOR_GRALLOC);
+    if (w->set_buffer_count(w, BUFFER_COUNT_FOR_GRALLOC)) {
+        LOGE("%s: could not set buffer count", __func__);
+        return INVALID_OPERATION;
+    }
+
+    int preview_width;
+    int preview_height;
+    mParameters.getPreviewSize(&preview_width, &preview_height);
+
+    int hal_pixel_format;
+
+    const char *str_preview_format = mParameters.getPreviewFormat();
+    LOGV("%s: str preview format %s width : %d height : %d ", __func__, str_preview_format, preview_width, preview_height);
+    mFrameSizeDelta = 16;
+
+    hal_pixel_format = HAL_PIXEL_FORMAT_YV12;
+
+    if (!strcmp(str_preview_format,
+                CameraParameters::PIXEL_FORMAT_RGB565)) {
+        hal_pixel_format = HAL_PIXEL_FORMAT_RGB_565;
+        mFrameSizeDelta = 0;
+    } else if (!strcmp(str_preview_format,
+                     CameraParameters::PIXEL_FORMAT_RGBA8888)) {
+        hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888;
+        mFrameSizeDelta = 0;
+    } else if (!strcmp(str_preview_format,
+                     CameraParameters::PIXEL_FORMAT_YUV420SP)) {
+        hal_pixel_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+    } else if (!strcmp(str_preview_format,
+                     CameraParameters::PIXEL_FORMAT_YUV420P))
+        hal_pixel_format = HAL_PIXEL_FORMAT_YV12;
+
+#ifdef USE_EGL
+    if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_ION)) {
+        LOGE("%s: could not set usage on gralloc buffer", __func__);
+        return INVALID_OPERATION;
+    }
+#else
+    if (w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN
+        | GRALLOC_USAGE_HWC_HWOVERLAY | GRALLOC_USAGE_HW_ION)) {
+        LOGE("%s: could not set usage on gralloc buffer", __func__);
+        return INVALID_OPERATION;
+    }
+#endif
+
+    if (w->set_buffers_geometry(w,
+                                preview_width, preview_height,
+                                hal_pixel_format)) {
+        LOGE("%s: could not set buffers geometry to %s",
+             __func__, str_preview_format);
+        return INVALID_OPERATION;
+    }
+
+    for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++)
+        if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[i], &mStride[i])) {
+            LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, i);
+            return INVALID_OPERATION;
+        }
+
+    if (mPreviewRunning && mPreviewStartDeferred) {
+        LOGV("start/resume preview");
+        status_t ret = startPreviewInternal();
+        if (ret == OK) {
+            mPreviewStartDeferred = false;
+            mPreviewCondition.signal();
+        }
+    }
+    mPreviewLock.unlock();
+
+    return OK;
+}
+
+void CameraHardwareSec::setCallbacks(camera_notify_callback notify_cb,
+                                     camera_data_callback data_cb,
+                                     camera_data_timestamp_callback data_cb_timestamp,
+                                     camera_request_memory get_memory,
+                                     void *user)
+{
+    mNotifyCb = notify_cb;
+    mDataCb = data_cb;
+    mDataCbTimestamp = data_cb_timestamp;
+    mGetMemoryCb = get_memory;
+    mCallbackCookie = user;
+}
+
+void CameraHardwareSec::enableMsgType(int32_t msgType)
+{
+    LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x",
+         __func__, msgType, mMsgEnabled);
+    mMsgEnabled |= msgType;
+
+    mPreviewLock.lock();
+    if ((msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_VIDEO_FRAME)) &&
+             mPreviewRunning && mPreviewStartDeferred) {
+        LOGV("%s: starting deferred preview", __func__);
+        if (startPreviewInternal() == OK) {
+            mPreviewStartDeferred = false;
+            mPreviewCondition.signal();
+        }
+    }
+    mPreviewLock.unlock();
+
+    LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
+}
+
+void CameraHardwareSec::disableMsgType(int32_t msgType)
+{
+    LOGV("%s : msgType = 0x%x, mMsgEnabled before = 0x%x",
+         __func__, msgType, mMsgEnabled);
+    mMsgEnabled &= ~msgType;
+    LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
+}
+
+bool CameraHardwareSec::msgTypeEnabled(int32_t msgType)
+{
+    return (mMsgEnabled & msgType);
+}
+
+void CameraHardwareSec::setSkipFrame(int frame)
+{
+    Mutex::Autolock lock(mSkipFrameLock);
+    if (frame < mSkipFrame)
+        return;
+
+    mSkipFrame = frame;
+}
+
+int CameraHardwareSec::previewThreadWrapper()
+{
+    LOGI("%s: starting", __func__);
+    while (1) {
+        mPreviewLock.lock();
+        while (!mPreviewRunning) {
+            LOGI("%s: calling mSecCamera->stopPreview() and waiting", __func__);
+            mSecCamera->stopPreview();
+            /* signal that we're stopping */
+            mPreviewStoppedCondition.signal();
+            mPreviewCondition.wait(mPreviewLock);
+            LOGI("%s: return from wait", __func__);
+        }
+        mPreviewLock.unlock();
+
+        if (mExitPreviewThread) {
+            LOGI("%s: exiting", __func__);
+            mSecCamera->stopPreview();
+            return 0;
+        }
+        previewThread();
+    }
+}
+
+int CameraHardwareSec::previewThread()
+{
+    int index;
+    nsecs_t timestamp;
+    SecBuffer previewAddr, recordAddr;
+    static int numArray = 0;
+    void *virAddr[3];
+    private_handle_t *hnd = NULL;
+
+    index = mSecCamera->getPreview();
+
+    if (index < 0) {
+        LOGE("ERR(%s):Fail on SecCamera->getPreview()", __func__);
+        if (mSecCamera->getPreviewState()) {
+            stopPreview();
+            startPreview();
+            mSecCamera->clearPreviewState();
+        }
+        return UNKNOWN_ERROR;
+    }
+
+    mSkipFrameLock.lock();
+    if (mSkipFrame > 0) {
+        mSkipFrame--;
+        mSkipFrameLock.unlock();
+        LOGV("%s: index %d skipping frame", __func__, index);
+        if (mSecCamera->setPreviewFrame(index) < 0) {
+            LOGE("%s: Could not qbuff[%d]!!", __func__, index);
+            return UNKNOWN_ERROR;
+        }
+        return NO_ERROR;
+    }
+    mSkipFrameLock.unlock();
+
+    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+
+    int width, height, frame_size, offset;
+
+    mSecCamera->getPreviewSize(&width, &height, &frame_size);
+
+    offset = frame_size * index;
+
+    if (mPreviewWindow && mGrallocHal && mPreviewRunning) {
+        hnd = (private_handle_t*)*mBufferHandle[index];
+
+        if (mPreviewHeap) {
+            mPreviewHeap->release(mPreviewHeap);
+            mPreviewHeap = 0;
+        }
+
+        mPreviewHeap = mGetMemoryCb(hnd->fd, frame_size, 1, 0);
+
+        hnd = NULL;
+
+        mGrallocHal->unlock(mGrallocHal, *mBufferHandle[index]);
+        if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[index])) {
+            LOGE("%s: Could not enqueue gralloc buffer[%d]!!", __func__, index);
+            goto callbacks;
+        }
+
+        numArray = index;
+
+        if (0 != mPreviewWindow->dequeue_buffer(mPreviewWindow, &mBufferHandle[numArray], &mStride[numArray])) {
+            LOGE("%s: Could not dequeue gralloc buffer[%d]!!", __func__, numArray);
+            goto callbacks;
+        }
+
+        if (!mGrallocHal->lock(mGrallocHal,
+                               *mBufferHandle[numArray],
+                               GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR,
+                               0, 0, width, height, virAddr)) {
+            mSecCamera->getPreviewAddr(index, &previewAddr);
+            char *frame = (char *)previewAddr.virt.extP[0];
+
+#ifdef USE_EGL
+            int m_Ywidth = ALIGN(width, 16);
+            int m_Yheight = ALIGN(height, 16);
+            int m_UVwidth = ALIGN(width/2, 8);
+            int m_UVheight = ALIGN(height/2, 8);
+            virAddr[1] = virAddr[0] + (m_Ywidth * m_Yheight);
+            virAddr[2] = virAddr[1] + (m_UVwidth * m_UVheight);
+#endif
+
+            mSecCamera->setUserBufferAddr(virAddr, index, PREVIEW_MODE);
+        }
+        else
+            LOGE("%s: could not obtain gralloc buffer", __func__);
+
+        if (mSecCamera->setPreviewFrame(index) < 0) {
+            LOGE("%s: Fail qbuf, index(%d)", __func__, index);
+            goto callbacks;
+        }
+        index = 0;
+    }
+
+callbacks:
+    // Notify the client of a new frame.
+    if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
+        mDataCb(CAMERA_MSG_PREVIEW_FRAME, mPreviewHeap, index, NULL, mCallbackCookie);
+
+    Mutex::Autolock lock(mRecordLock);
+    if (mRecordRunning == true) {
+        int recordingIndex = 0;
+
+        index = mSecCamera->getRecordFrame();
+        if (index < 0) {
+            LOGE("ERR(%s):Fail on SecCamera->getRecordFrame()", __func__);
+            return UNKNOWN_ERROR;
+        }
+
+        numArray = index;
+
+        // Notify the client of a new frame.
+        if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)
+            mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME,
+                             mRecordHeap[numArray], recordingIndex, mCallbackCookie);
+        else
+            mSecCamera->releaseRecordFrame(index);
+    }
+
+    return NO_ERROR;
+}
+
+status_t CameraHardwareSec::startPreview()
+{
+    int ret = 0;
+
+    LOGV("%s :", __func__);
+
+    Mutex::Autolock lock(mStateLock);
+    if (mCaptureInProgress) {
+        LOGE("%s : capture in progress, not allowed", __func__);
+        return INVALID_OPERATION;
+    }
+
+    mPreviewLock.lock();
+    if (mPreviewRunning) {
+        // already running
+        LOGE("%s : preview thread already running", __func__);
+        mPreviewLock.unlock();
+        return INVALID_OPERATION;
+    }
+
+    mPreviewRunning = true;
+    mPreviewStartDeferred = false;
+
+    if (!mPreviewWindow &&
+            !(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) &&
+            !(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+        LOGI("%s : deferring", __func__);
+        mPreviewStartDeferred = true;
+        mPreviewLock.unlock();
+        return NO_ERROR;
+    }
+
+    ret = startPreviewInternal();
+    if (ret == OK)
+        mPreviewCondition.signal();
+
+    mPreviewLock.unlock();
+    return ret;
+}
+
+status_t CameraHardwareSec::startPreviewInternal()
+{
+    LOGV("%s", __func__);
+    int width, height, frame_size;
+
+    mSecCamera->getPreviewSize(&width, &height, &frame_size);
+    LOGD("mPreviewHeap(fd(%d), size(%d), width(%d), height(%d))",
+         mSecCamera->getCameraFd(), frame_size + mFrameSizeDelta, width, height);
+
+    void *vaddr[3];
+
+    for (int i = 0; i < MAX_BUFFERS; i++) {
+        !mGrallocHal->lock(mGrallocHal,
+                           *mBufferHandle[i],
+                           GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_YUV_ADDR,
+                           0, 0, width, height, vaddr);
+        memset(vaddr[0], 0, width*height*2);
+        int m_Ywidth = ALIGN(width, 16);
+        int m_Yheight = ALIGN(height, 16);
+        int m_UVwidth = ALIGN(width/2, 8);
+        int m_UVheight = ALIGN(height/2, 8);
+        vaddr[1] = vaddr[0] + (m_Ywidth * m_Yheight);
+        vaddr[2] = vaddr[1] + (m_UVwidth * m_UVheight);
+        mSecCamera->setUserBufferAddr(vaddr, i, PREVIEW_MODE);
+    }
+
+    int ret  = mSecCamera->startPreview();
+    LOGV("%s : mSecCamera->startPreview() returned %d", __func__, ret);
+
+    if (ret < 0) {
+        LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    setSkipFrame(INITIAL_SKIP_FRAME);
+
+    if (mPreviewHeap) {
+        mPreviewHeap->release(mPreviewHeap);
+        mPreviewHeap = 0;
+    }
+
+    mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
+    LOGV("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",
+         mPostViewWidth,mPostViewHeight,mPostViewSize);
+
+    return NO_ERROR;
+}
+
+void CameraHardwareSec::stopPreviewInternal()
+{
+    LOGV("%s :", __func__);
+
+    /* request that the preview thread stop. */
+    if (mPreviewRunning) {
+        mPreviewRunning = false;
+        if (!mPreviewStartDeferred) {
+            mPreviewCondition.signal();
+            /* wait until preview thread is stopped */
+            mPreviewStoppedCondition.wait(mPreviewLock);
+
+            for (int i = 0; i < MAX_BUFFERS; i++) {
+                if (0 != mPreviewWindow->enqueue_buffer(mPreviewWindow, mBufferHandle[i]))
+                    LOGE("%s: Fail to enqueue buffer[%d]", __func__, i);
+            }
+        }
+        else
+            LOGV("%s : preview running but deferred, doing nothing", __func__);
+    } else
+        LOGI("%s : preview not running, doing nothing", __func__);
+}
+
+void CameraHardwareSec::stopPreview()
+{
+    LOGV("%s :", __func__);
+
+    /* request that the preview thread stop. */
+    mPreviewLock.lock();
+    stopPreviewInternal();
+    mPreviewLock.unlock();
+}
+
+bool CameraHardwareSec::previewEnabled()
+{
+    Mutex::Autolock lock(mPreviewLock);
+    LOGV("%s : %d", __func__, mPreviewRunning);
+    return mPreviewRunning;
+}
+
+status_t CameraHardwareSec::startRecording()
+{
+    LOGV("%s :", __func__);
+
+    Mutex::Autolock lock(mRecordLock);
+
+    for(int i = 0; i<BUFFER_COUNT_FOR_ARRAY; i++){
+        if (mRecordHeap[i] != NULL) {
+            mRecordHeap[i]->release(mRecordHeap[i]);
+            mRecordHeap[i] = 0;
+        }
+
+        int width, height;
+
+        mSecCamera->getRecordingSize(&width, &height);
+        mRecordHeap[i] = mGetMemoryCb(-1, (ALIGN((ALIGN(width, 16) * ALIGN(height, 16)), 2048)
+	                   + ALIGN((ALIGN(width, 16) * ALIGN(height >> 1, 8)), 2048)), 1, NULL);
+        mSecCamera->setUserBufferAddr((void *)(mRecordHeap[i]->data), i, RECORD_MODE);
+        if (!mRecordHeap[i]) {
+            LOGE("ERR(%s): Record heap[%d] creation fail", __func__, i);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    LOGV("mRecordHeaps alloc done");
+
+    if (mRecordRunning == false) {
+        if (mSecCamera->startRecord() < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __func__);
+            return UNKNOWN_ERROR;
+        }
+        mRecordRunning = true;
+    }
+    return NO_ERROR;
+}
+
+void CameraHardwareSec::stopRecording()
+{
+    LOGV("%s :", __func__);
+
+    Mutex::Autolock lock(mRecordLock);
+
+    if (mRecordRunning == true) {
+        if (mSecCamera->stopRecord() < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __func__);
+            return;
+        }
+        mRecordRunning = false;
+    }
+}
+
+bool CameraHardwareSec::recordingEnabled()
+{
+    LOGV("%s :", __func__);
+    LOGV("%s : %d", __func__, mPreviewRunning);
+
+    return mRecordRunning;
+}
+
+void CameraHardwareSec::releaseRecordingFrame(const void *opaque)
+{
+    int i;
+    for (i = 0; i < MAX_BUFFERS; i++)
+        if ((char *)mRecordHeap[i]->data == (char *)opaque)
+            break;
+
+    mSecCamera->releaseRecordFrame(i);
+}
+
+int CameraHardwareSec::autoFocusThread()
+{
+    int count =0;
+    int af_status =0 ;
+
+    LOGV("%s : starting", __func__);
+
+
+    /* block until we're told to start.  we don't want to use
+     * a restartable thread and requestExitAndWait() in cancelAutoFocus()
+     * because it would cause deadlock between our callbacks and the
+     * caller of cancelAutoFocus() which both want to grab the same lock
+     * in CameraServices layer.
+     */
+    mFocusLock.lock();
+    /* check early exit request */
+    if (mExitAutoFocusThread) {
+        mFocusLock.unlock();
+        LOGV("%s : exiting on request0", __func__);
+        return NO_ERROR;
+    }
+    mFocusCondition.wait(mFocusLock);
+    /* check early exit request */
+    if (mExitAutoFocusThread) {
+        mFocusLock.unlock();
+        LOGV("%s : exiting on request1", __func__);
+        return NO_ERROR;
+    }
+    mFocusLock.unlock();
+
+#ifdef GAIA_FW_BETA
+    if (mMsgEnabled & CAMERA_MSG_FOCUS)
+        mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie);
+
+    //LOGV("%s : exiting with no error", __func__);
+    return NO_ERROR;
+#else
+
+#ifdef AF_SUPPORT
+    LOGV("%s : calling setAutoFocus", __func__);
+    if (mSecCamera->setAutofocus() < 0) {
+        LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    af_status = mSecCamera->getAutoFocusResult();
+#else
+    sleep(1);
+    af_status = 0x02;
+#endif
+
+    if (af_status == 0x01) {
+        LOGV("%s : AF Success!!", __func__);
+        if (mMsgEnabled & CAMERA_MSG_FOCUS)
+            mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
+    } else if (af_status == 0x02) {
+        LOGV("%s : AF Cancelled !!", __func__);
+        if (mMsgEnabled & CAMERA_MSG_FOCUS) {
+            /* CAMERA_MSG_FOCUS only takes a bool.  true for
+             * finished and false for failure.  cancel is still
+             * considered a true result.
+             */
+            mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
+        }
+    } else {
+        LOGV("%s : AF Fail !!", __func__);
+        LOGV("%s : mMsgEnabled = 0x%x", __func__, mMsgEnabled);
+        if (mMsgEnabled & CAMERA_MSG_FOCUS)
+            mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie);
+    }
+
+    LOGV("%s : exiting with no error", __func__);
+    return NO_ERROR;
+#endif
+}
+
+status_t CameraHardwareSec::autoFocus()
+{
+    LOGV("%s :", __func__);
+    /* signal autoFocusThread to run once */
+    mFocusCondition.signal();
+    return NO_ERROR;
+}
+
+status_t CameraHardwareSec::cancelAutoFocus()
+{
+    LOGV("%s :", __func__);
+#ifndef GAIA_FW_BETA
+
+    if (mSecCamera->cancelAutofocus() < 0) {
+        LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __func__);
+        return UNKNOWN_ERROR;
+    }
+#endif
+    return NO_ERROR;
+}
+
+int CameraHardwareSec::save_jpeg( unsigned char *real_jpeg, int jpeg_size)
+{
+    FILE *yuv_fp = NULL;
+    char filename[100], *buffer = NULL;
+
+    /* file create/open, note to "wb" */
+    yuv_fp = fopen("/data/camera_dump.jpeg", "wb");
+    if (yuv_fp == NULL) {
+        LOGE("Save jpeg file open error");
+        return -1;
+    }
+
+    LOGV("[BestIQ]  real_jpeg size ========>  %d", jpeg_size);
+    buffer = (char *) malloc(jpeg_size);
+    if (buffer == NULL) {
+        LOGE("Save YUV] buffer alloc failed");
+        if (yuv_fp)
+            fclose(yuv_fp);
+
+        return -1;
+    }
+
+    memcpy(buffer, real_jpeg, jpeg_size);
+
+    fflush(stdout);
+
+    fwrite(buffer, 1, jpeg_size, yuv_fp);
+
+    fflush(yuv_fp);
+
+    if (yuv_fp)
+            fclose(yuv_fp);
+    if (buffer)
+            free(buffer);
+
+    return 0;
+}
+
+void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t size)
+{
+    int nw;
+    int cnt = 0;
+    uint32_t written = 0;
+
+    LOGD("opening file [%s]", fname);
+    int fd = open(fname, O_RDWR | O_CREAT);
+    if (fd < 0) {
+        LOGE("failed to create file [%s]: %s", fname, strerror(errno));
+        return;
+    }
+
+    LOGD("writing %d bytes to file [%s]", size, fname);
+    while (written < size) {
+        nw = ::write(fd, buf + written, size - written);
+        if (nw < 0) {
+            LOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno));
+            break;
+        }
+        written += nw;
+        cnt++;
+    }
+    LOGD("done writing %d bytes to file [%s] in %d passes",size, fname, cnt);
+    ::close(fd);
+}
+
+bool CameraHardwareSec::scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHeight,
+                                        char *dstBuf, uint32_t dstWidth, uint32_t dstHeight)
+{
+    int32_t step_x, step_y;
+    int32_t iXsrc, iXdst;
+    int32_t x, y, src_y_start_pos, dst_pos, src_pos;
+
+    if (dstWidth % 2 != 0 || dstHeight % 2 != 0) {
+        LOGE("scale_down_yuv422: invalid width, height for scaling");
+        return false;
+    }
+
+    step_x = srcWidth / dstWidth;
+    step_y = srcHeight / dstHeight;
+
+    dst_pos = 0;
+    for (uint32_t y = 0; y < dstHeight; y++) {
+        src_y_start_pos = (y * step_y * (srcWidth * 2));
+
+        for (uint32_t x = 0; x < dstWidth; x += 2) {
+            src_pos = src_y_start_pos + (x * (step_x * 2));
+
+            dstBuf[dst_pos++] = srcBuf[src_pos    ];
+            dstBuf[dst_pos++] = srcBuf[src_pos + 1];
+            dstBuf[dst_pos++] = srcBuf[src_pos + 2];
+            dstBuf[dst_pos++] = srcBuf[src_pos + 3];
+        }
+    }
+
+    return true;
+}
+
+bool CameraHardwareSec::YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight)
+{
+    int32_t        x, y, src_y_start_pos, dst_cbcr_pos, dst_pos, src_pos;
+    unsigned char *srcBufPointer = (unsigned char *)srcBuf;
+    unsigned char *dstBufPointer = (unsigned char *)dstBuf;
+
+    dst_pos = 0;
+    dst_cbcr_pos = srcWidth*srcHeight;
+    for (uint32_t y = 0; y < srcHeight; y++) {
+        src_y_start_pos = (y * (srcWidth * 2));
+
+        for (uint32_t x = 0; x < (srcWidth * 2); x += 2) {
+            src_pos = src_y_start_pos + x;
+
+            dstBufPointer[dst_pos++] = srcBufPointer[src_pos];
+        }
+    }
+    for (uint32_t y = 0; y < srcHeight; y += 2) {
+        src_y_start_pos = (y * (srcWidth * 2));
+
+        for (uint32_t x = 0; x < (srcWidth * 2); x += 4) {
+            src_pos = src_y_start_pos + x;
+
+            dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 3];
+            dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 1];
+        }
+    }
+
+    return true;
+}
+
+int CameraHardwareSec::pictureThread()
+{
+    LOGV("%s :", __func__);
+
+    int jpeg_size = 0;
+    int ret = NO_ERROR;
+    unsigned char *jpeg_data = NULL;
+    int postview_offset = 0;
+    unsigned char *postview_data = NULL;
+
+    unsigned char *addr = NULL;
+    int mPostViewWidth, mPostViewHeight, mPostViewSize;
+    int mThumbWidth, mThumbHeight, mThumbSize;
+    int cap_width, cap_height, cap_frame_size;
+
+    unsigned int output_size = 0;
+
+    mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize);
+    mSecCamera->getThumbnailConfig(&mThumbWidth, &mThumbHeight, &mThumbSize);
+    int postviewHeapSize = mPostViewSize;
+    mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size);
+    int mJpegHeapSize;
+#ifdef JPEG_FROM_SENSOR
+    if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK)
+        mJpegHeapSize = cap_frame_size * SecCamera::getJpegRatio();
+    else
+#endif
+        mJpegHeapSize = cap_frame_size;
+
+    //sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, mPostViewSize + 8);
+
+    LOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight);
+
+    camera_memory_t *JpegHeap = mGetMemoryCb(-1, mJpegHeapSize, 1, 0);
+#ifndef GAIA_FW_BETA
+    sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBaseIon(mPostViewSize);
+    sp<MemoryHeapBase> ThumbnailHeap = new MemoryHeapBaseIon(mThumbSize);
+#else
+    sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBase(mPostViewSize);
+    sp<MemoryHeapBase> ThumbnailHeap = new MemoryHeapBase(mThumbSize);
+#endif
+
+    if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
+        int picture_size, picture_width, picture_height;
+        mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size);
+        int picture_format = mSecCamera->getSnapshotPixelFormat();
+
+        unsigned int phyAddr;
+
+        // Modified the shutter sound timing for Jpeg capture
+#ifdef JPEG_FROM_SENSOR
+        if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK)
+            mSecCamera->setSnapshotCmd();
+        if (mMsgEnabled & CAMERA_MSG_SHUTTER)
+            mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
+        if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){
+            jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr);
+            if (jpeg_data == NULL) {
+                LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __func__);
+                ret = UNKNOWN_ERROR;
+            }
+        } else {
+#endif
+            if (mMsgEnabled & CAMERA_MSG_SHUTTER)
+                mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
+            if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(),
+                    (unsigned char*)JpegHeap->data, &output_size) < 0) {
+                mStateLock.lock();
+                mCaptureInProgress = false;
+                mStateLock.unlock();
+                JpegHeap->release(JpegHeap);
+                return UNKNOWN_ERROR;
+            }
+            LOGI("snapshotandjpeg done");
+#ifdef JPEG_FROM_SENSOR
+        }
+#endif
+    }
+
+    int JpegImageSize, JpegExifSize;
+    bool isLSISensor = false;
+
+#ifdef JPEG_FROM_SENSOR
+    if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
+        LOGV("%s, %s", __func__, (const char*)mCameraSensorName);   //to check sensor name
+        isLSISensor = !strncmp((const char*)mCameraSensorName, "S5K4ECGX", 8);
+        if (isLSISensor) {
+            LOGI("== Camera Sensor Detect %s - Samsung LSI SOC 5M ==", mCameraSensorName);
+            // LSI 5M SOC
+            if (!SplitFrame(jpeg_data, SecCamera::getInterleaveDataSize(),
+                            SecCamera::getJpegLineLength(),
+                            mPostViewWidth * 2, mPostViewWidth,
+                            JpegHeap->data, &JpegImageSize,
+                            PostviewHeap->base(), &mPostViewSize)) {
+                JpegHeap->release(JpegHeap);
+                return UNKNOWN_ERROR;
+            }
+        } else {
+            LOGI("== Camera Sensor Detect %s Sony SOC 5M ==", mCameraSensorName);
+            decodeInterleaveData(jpeg_data,
+                                 SecCamera::getInterleaveDataSize(),
+                                 mPostViewWidth, mPostViewHeight,
+                                 &JpegImageSize, JpegHeap->data, PostviewHeap->base());
+        }
+    } else
+#endif
+        JpegImageSize = static_cast<int>(output_size);
+
+    scaleDownYuv422((char *)mSecCamera->getPictureVaddr(), mPostViewWidth, mPostViewHeight,
+                    (char *)ThumbnailHeap->base(), mThumbWidth, mThumbHeight);
+
+#ifdef GAIA_FW_BETA
+    int rawHeapSize = mPostViewSize;
+    LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize);
+    mRawHeap = mGetMemoryCb((int)mSecCamera->getCameraFd(), rawHeapSize, 1, 0);
+    if (!mRawHeap)
+        LOGE("ERR(%s): Raw heap creation fail", __func__);
+
+    if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)
+        mDataCb(CAMERA_MSG_RAW_IMAGE, mRawHeap, 0, NULL, mCallbackCookie);
+#endif
+
+    mStateLock.lock();
+    mCaptureInProgress = false;
+    mStateLock.unlock();
+
+    if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
+        camera_memory_t *ExifHeap =
+            mGetMemoryCb(-1, EXIF_FILE_SIZE + mThumbSize, 1, 0);
+
+        JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->data,
+                                           (unsigned char *)ThumbnailHeap->base());
+        LOGV("JpegExifSize=%d", JpegExifSize);
+
+        if (JpegExifSize < 0) {
+            ret = UNKNOWN_ERROR;
+            goto out;
+        }
+
+        int mJpegHeapSize_out = JpegImageSize + JpegExifSize;
+        camera_memory_t *JpegHeap_out = mGetMemoryCb(-1, mJpegHeapSize_out, 1, 0);
+
+        unsigned char *ExifStart = (unsigned char *)JpegHeap_out->data + 2;
+        unsigned char *ImageStart = ExifStart + JpegExifSize;
+
+        memcpy(JpegHeap_out->data, JpegHeap->data, 2);
+        memcpy(ExifStart, ExifHeap->data, JpegExifSize);
+        memcpy(ImageStart, JpegHeap->data + 2, JpegImageSize - 2);
+
+        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, JpegHeap_out, 0, NULL, mCallbackCookie);
+
+        if (ExifHeap) {
+            ExifHeap->release(ExifHeap);
+            ExifHeap = 0;
+        }
+
+        if (JpegHeap_out) {
+            JpegHeap_out->release(JpegHeap_out);
+            JpegHeap_out = 0;
+        }
+    }
+
+    LOGV("%s : pictureThread end", __func__);
+
+out:
+    if (JpegHeap) {
+        JpegHeap->release(JpegHeap);
+        JpegHeap = 0;
+    }
+
+    if (mRawHeap) {
+        mRawHeap->release(mRawHeap);
+        mRawHeap = 0;
+    }
+
+    return ret;
+}
+
+status_t CameraHardwareSec::takePicture()
+{
+    LOGV("%s :", __func__);
+
+    stopPreview();
+
+    Mutex::Autolock lock(mStateLock);
+    if (mCaptureInProgress) {
+        LOGE("%s : capture already in progress", __func__);
+        return INVALID_OPERATION;
+    }
+
+    if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {
+        LOGE("%s : couldn't run picture thread", __func__);
+        return INVALID_OPERATION;
+    }
+    mCaptureInProgress = true;
+
+    return NO_ERROR;
+}
+
+status_t CameraHardwareSec::cancelPicture()
+{
+    LOGV("%s", __func__);
+
+    if (mPictureThread.get()) {
+        LOGV("%s: waiting for picture thread to exit", __func__);
+        mPictureThread->requestExitAndWait();
+        LOGV("%s: picture thread has exited", __func__);
+    }
+
+    return NO_ERROR;
+}
+
+bool CameraHardwareSec::CheckVideoStartMarker(unsigned char *pBuf)
+{
+    if (!pBuf) {
+        LOGE("CheckVideoStartMarker() => pBuf is NULL");
+        return false;
+    }
+
+    if (HIBYTE(VIDEO_COMMENT_MARKER_H) == * pBuf      && LOBYTE(VIDEO_COMMENT_MARKER_H) == *(pBuf + 1) &&
+        HIBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 2) && LOBYTE(VIDEO_COMMENT_MARKER_L) == *(pBuf + 3))
+        return true;
+
+    return false;
+}
+
+bool CameraHardwareSec::CheckEOIMarker(unsigned char *pBuf)
+{
+    if (!pBuf) {
+        LOGE("CheckEOIMarker() => pBuf is NULL");
+        return false;
+    }
+
+    // EOI marker [FF D9]
+    if (HIBYTE(JPEG_EOI_MARKER) == *pBuf && LOBYTE(JPEG_EOI_MARKER) == *(pBuf + 1))
+        return true;
+
+    return false;
+}
+
+bool CameraHardwareSec::FindEOIMarkerInJPEG(unsigned char *pBuf, int dwBufSize, int *pnJPEGsize)
+{
+    if (NULL == pBuf || 0 >= dwBufSize) {
+        LOGE("FindEOIMarkerInJPEG() => There is no contents.");
+        return false;
+    }
+
+    unsigned char *pBufEnd = pBuf + dwBufSize;
+
+    while (pBuf < pBufEnd) {
+        if (CheckEOIMarker(pBuf++))
+            return true;
+
+        (*pnJPEGsize)++;
+    }
+
+    return false;
+}
+
+bool CameraHardwareSec::SplitFrame(unsigned char *pFrame, int dwSize,
+                    int dwJPEGLineLength, int dwVideoLineLength, int dwVideoHeight,
+                    void *pJPEG, int *pdwJPEGSize,
+                    void *pVideo, int *pdwVideoSize)
+{
+    LOGV("===========SplitFrame Start==============");
+
+    if (NULL == pFrame || 0 >= dwSize) {
+        LOGE("There is no contents (pFrame=%p, dwSize=%d", pFrame, dwSize);
+        return false;
+    }
+
+    if (0 == dwJPEGLineLength || 0 == dwVideoLineLength) {
+        LOGE("There in no input information for decoding interleaved jpeg");
+        return false;
+    }
+
+    unsigned char *pSrc = pFrame;
+    unsigned char *pSrcEnd = pFrame + dwSize;
+
+    unsigned char *pJ = (unsigned char *)pJPEG;
+    int dwJSize = 0;
+    unsigned char *pV = (unsigned char *)pVideo;
+    int dwVSize = 0;
+
+    bool bRet = false;
+    bool isFinishJpeg = false;
+
+    while (pSrc < pSrcEnd) {
+        // Check video start marker
+        if (CheckVideoStartMarker(pSrc)) {
+            int copyLength;
+
+            if (pSrc + dwVideoLineLength <= pSrcEnd)
+                copyLength = dwVideoLineLength;
+            else
+                copyLength = pSrcEnd - pSrc - VIDEO_COMMENT_MARKER_LENGTH;
+
+            // Copy video data
+            if (pV) {
+                memcpy(pV, pSrc + VIDEO_COMMENT_MARKER_LENGTH, copyLength);
+                pV += copyLength;
+                dwVSize += copyLength;
+            }
+
+            pSrc += copyLength + VIDEO_COMMENT_MARKER_LENGTH;
+        } else {
+            // Copy pure JPEG data
+            int size = 0;
+            int dwCopyBufLen = dwJPEGLineLength <= pSrcEnd-pSrc ? dwJPEGLineLength : pSrcEnd - pSrc;
+
+            if (FindEOIMarkerInJPEG((unsigned char *)pSrc, dwCopyBufLen, &size)) {
+                isFinishJpeg = true;
+                size += 2;  // to count EOF marker size
+            } else {
+                if ((dwCopyBufLen == 1) && (pJPEG < pJ)) {
+                    unsigned char checkBuf[2] = { *(pJ - 1), *pSrc };
+
+                    if (CheckEOIMarker(checkBuf))
+                        isFinishJpeg = true;
+                }
+                size = dwCopyBufLen;
+            }
+
+            memcpy(pJ, pSrc, size);
+
+            dwJSize += size;
+
+            pJ += dwCopyBufLen;
+            pSrc += dwCopyBufLen;
+        }
+        if (isFinishJpeg)
+            break;
+    }
+
+    if (isFinishJpeg) {
+        bRet = true;
+        if (pdwJPEGSize)
+            *pdwJPEGSize = dwJSize;
+        if (pdwVideoSize)
+            *pdwVideoSize = dwVSize;
+    } else {
+        LOGE("DecodeInterleaveJPEG_WithOutDT() => Can not find EOI");
+        bRet = false;
+        if (pdwJPEGSize)
+            *pdwJPEGSize = 0;
+        if (pdwVideoSize)
+            *pdwVideoSize = 0;
+    }
+    LOGV("===========SplitFrame end==============");
+
+    return bRet;
+}
+
+int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData,
+                                                 int interleaveDataSize,
+                                                 int yuvWidth,
+                                                 int yuvHeight,
+                                                 int *pJpegSize,
+                                                 void *pJpegData,
+                                                 void *pYuvData)
+{
+    if (pInterleaveData == NULL)
+        return false;
+
+    bool ret = true;
+    unsigned int *interleave_ptr = (unsigned int *)pInterleaveData;
+    unsigned char *jpeg_ptr = (unsigned char *)pJpegData;
+    unsigned char *yuv_ptr = (unsigned char *)pYuvData;
+    unsigned char *p;
+    int jpeg_size = 0;
+    int yuv_size = 0;
+
+    int i = 0;
+
+    LOGV("decodeInterleaveData Start~~~");
+    while (i < interleaveDataSize) {
+        if ((*interleave_ptr == 0xFFFFFFFF) || (*interleave_ptr == 0x02FFFFFF) ||
+                (*interleave_ptr == 0xFF02FFFF)) {
+            // Padding Data
+            interleave_ptr++;
+            i += 4;
+        } else if ((*interleave_ptr & 0xFFFF) == 0x05FF) {
+            // Start-code of YUV Data
+            p = (unsigned char *)interleave_ptr;
+            p += 2;
+            i += 2;
+
+            // Extract YUV Data
+            if (pYuvData != NULL) {
+                memcpy(yuv_ptr, p, yuvWidth * 2);
+                yuv_ptr += yuvWidth * 2;
+                yuv_size += yuvWidth * 2;
+            }
+            p += yuvWidth * 2;
+            i += yuvWidth * 2;
+
+            // Check End-code of YUV Data
+            if ((*p == 0xFF) && (*(p + 1) == 0x06)) {
+                interleave_ptr = (unsigned int *)(p + 2);
+                i += 2;
+            } else {
+                ret = false;
+                break;
+            }
+        } else {
+            // Extract JPEG Data
+            if (pJpegData != NULL) {
+                memcpy(jpeg_ptr, interleave_ptr, 4);
+                jpeg_ptr += 4;
+                jpeg_size += 4;
+            }
+            interleave_ptr++;
+            i += 4;
+        }
+    }
+    if (ret) {
+        if (pJpegData != NULL) {
+            // Remove Padding after EOI
+            for (i = 0; i < 3; i++) {
+                if (*(--jpeg_ptr) != 0xFF) {
+                    break;
+                }
+                jpeg_size--;
+            }
+            *pJpegSize = jpeg_size;
+
+        }
+        // Check YUV Data Size
+        if (pYuvData != NULL) {
+            if (yuv_size != (yuvWidth * yuvHeight * 2)) {
+                ret = false;
+            }
+        }
+    }
+    LOGV("decodeInterleaveData End~~~");
+    return ret;
+}
+
+status_t CameraHardwareSec::dump(int fd) const
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    const Vector<String16> args;
+
+    if (mSecCamera != 0) {
+        mSecCamera->dump(fd);
+        mParameters.dump(fd, args);
+        mInternalParameters.dump(fd, args);
+        snprintf(buffer, 255, " preview running(%s)\n", mPreviewRunning?"true": "false");
+        result.append(buffer);
+    } else
+        result.append("No camera client yet.\n");
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+bool CameraHardwareSec::isSupportedPreviewSize(const int width,
+                                               const int height) const
+{
+    unsigned int i;
+
+    for (i = 0; i < mSupportedPreviewSizes.size(); i++) {
+        if (mSupportedPreviewSizes[i].width == width &&
+                mSupportedPreviewSizes[i].height == height)
+            return true;
+    }
+
+    return false;
+}
+
+status_t CameraHardwareSec::setParameters(const CameraParameters& params)
+{
+    LOGV("%s :", __func__);
+#ifndef GAIA_FW_BETA
+    int Internal_is = !strncmp((const char*)mSecCamera->getCameraSensorName(), "ISP Camera", 10);
+#else
+    int Internal_is = 0;
+#endif
+    status_t ret = NO_ERROR;
+
+    /* if someone calls us while picture thread is running, it could screw
+     * up the sensor quite a bit so return error.  we can't wait because
+     * that would cause deadlock with the callbacks
+     */
+    mStateLock.lock();
+    if (mCaptureInProgress) {
+        mStateLock.unlock();
+        LOGE("%s : capture in progress, not allowed", __func__);
+        return UNKNOWN_ERROR;
+    }
+    mStateLock.unlock();
+
+    // preview size
+#ifdef GAIA_FW_BETA
+    int new_preview_width  = 1920;
+    int new_preview_height = 1080;
+#else
+    int new_preview_width  = 0;
+    int new_preview_height = 0;
+    params.getPreviewSize(&new_preview_width, &new_preview_height);
+#endif
+    const char *new_str_preview_format = params.getPreviewFormat();
+    LOGV("%s : new_preview_width x new_preview_height = %dx%d, format = %s",
+         __func__, new_preview_width, new_preview_height, new_str_preview_format);
+
+    if (0 < new_preview_width && 0 < new_preview_height &&
+            new_str_preview_format != NULL &&
+            isSupportedPreviewSize(new_preview_width, new_preview_height)) {
+        int new_preview_format = 0;
+
+        mFrameSizeDelta = 16;
+        if (!strcmp(new_str_preview_format,
+                    CameraParameters::PIXEL_FORMAT_RGB565)) {
+            new_preview_format = V4L2_PIX_FMT_RGB565;
+            mFrameSizeDelta = 0;
+        }
+        else if (!strcmp(new_str_preview_format,
+                         CameraParameters::PIXEL_FORMAT_RGBA8888)) {
+            new_preview_format = V4L2_PIX_FMT_RGB32;
+            mFrameSizeDelta = 0;
+        }
+        else if (!strcmp(new_str_preview_format,
+                         CameraParameters::PIXEL_FORMAT_YUV420SP))
+            new_preview_format = V4L2_PIX_FMT_NV21;
+        else if (!strcmp(new_str_preview_format,
+                         CameraParameters::PIXEL_FORMAT_YUV420P))
+            new_preview_format = V4L2_PIX_FMT_YVU420M;
+
+        else if (!strcmp(new_str_preview_format, "yuv420sp_custom"))
+            new_preview_format = V4L2_PIX_FMT_NV12T;
+        else if (!strcmp(new_str_preview_format, "yuv422i"))
+            new_preview_format = V4L2_PIX_FMT_YUYV;
+        else if (!strcmp(new_str_preview_format, "yuv422p"))
+            new_preview_format = V4L2_PIX_FMT_YUV422P;
+        else
+            new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party
+
+        int current_preview_width, current_preview_height, current_frame_size;
+        mSecCamera->getPreviewSize(&current_preview_width,
+                                   &current_preview_height,
+                                   &current_frame_size);
+        int current_pixel_format = mSecCamera->getPreviewPixelFormat();
+
+        if (current_preview_width != new_preview_width ||
+                    current_preview_height != new_preview_height ||
+                    current_pixel_format != new_preview_format) {
+            if (mSecCamera->setPreviewSize(new_preview_width, new_preview_height,
+                                           new_preview_format) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))",
+                     __func__, new_preview_width, new_preview_height, new_preview_format);
+                ret = UNKNOWN_ERROR;
+            } else {
+                if (mPreviewWindow) {
+                    if (mPreviewRunning && !mPreviewStartDeferred) {
+                        LOGE("ERR(%s): preview is running, cannot change size and format!",
+                        __func__);
+                        ret = INVALID_OPERATION;
+                    }
+
+                    LOGV("%s: mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
+                    LOGV("%s: mPreviewWindow->set_buffers_geometry (%p)", __func__,
+                         mPreviewWindow->set_buffers_geometry);
+                    mPreviewWindow->set_buffers_geometry(mPreviewWindow,
+                                                         new_preview_width, new_preview_height,
+                                                         new_preview_format);
+                    LOGV("%s: DONE mPreviewWindow (%p) set_buffers_geometry", __func__, mPreviewWindow);
+                }
+                mParameters.setPreviewSize(new_preview_width, new_preview_height);
+                mParameters.setPreviewFormat(new_str_preview_format);
+            }
+        }
+        else LOGV("%s: preview size and format has not changed", __func__);
+    } else {
+        LOGE("%s: Invalid preview size(%dx%d)",
+                __func__, new_preview_width, new_preview_height);
+
+        ret = INVALID_OPERATION;
+    }
+
+#ifndef GAIA_FW_BETA
+    int new_picture_width  = 0;
+    int new_picture_height = 0;
+
+    params.getPictureSize(&new_picture_width, &new_picture_height);
+    LOGV("%s : new_picture_width x new_picture_height = %dx%d", __func__, new_picture_width, new_picture_height);
+    if (0 < new_picture_width && 0 < new_picture_height) {
+        LOGV("%s: setSnapshotSize", __func__);
+        if (mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))",
+                    __func__, new_picture_width, new_picture_height);
+            ret = UNKNOWN_ERROR;
+        } else
+            mParameters.setPictureSize(new_picture_width, new_picture_height);
+    }
+
+    // picture format
+    const char *new_str_picture_format = params.getPictureFormat();
+    LOGV("%s : new_str_picture_format %s", __func__, new_str_picture_format);
+    if (new_str_picture_format != NULL) {
+        int new_picture_format = 0;
+
+        if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGB565))
+            new_picture_format = V4L2_PIX_FMT_RGB565;
+        else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_RGBA8888))
+            new_picture_format = V4L2_PIX_FMT_RGB32;
+        else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_YUV420SP))
+            new_picture_format = V4L2_PIX_FMT_NV21;
+        else if (!strcmp(new_str_picture_format, "yuv420sp_custom"))
+            new_picture_format = V4L2_PIX_FMT_NV12T;
+        else if (!strcmp(new_str_picture_format, "yuv420p"))
+            new_picture_format = V4L2_PIX_FMT_YUV420;
+        else if (!strcmp(new_str_picture_format, "yuv422i"))
+            new_picture_format = V4L2_PIX_FMT_YUYV;
+        else if (!strcmp(new_str_picture_format, "uyv422i_custom")) //Zero copy UYVY format
+            new_picture_format = V4L2_PIX_FMT_UYVY;
+        else if (!strcmp(new_str_picture_format, "uyv422i")) //Non-zero copy UYVY format
+            new_picture_format = V4L2_PIX_FMT_UYVY;
+        else if (!strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_JPEG))
+            new_picture_format = V4L2_PIX_FMT_YUYV;
+        else if (!strcmp(new_str_picture_format, "yuv422p"))
+            new_picture_format = V4L2_PIX_FMT_YUV422P;
+        else
+            new_picture_format = V4L2_PIX_FMT_NV21; //for 3rd party
+
+        if (mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __func__, new_picture_format);
+            ret = UNKNOWN_ERROR;
+        } else
+            mParameters.setPictureFormat(new_str_picture_format);
+    }
+
+    // JPEG image quality
+    int new_jpeg_quality = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
+    LOGV("%s : new_jpeg_quality %d", __func__, new_jpeg_quality);
+    /* we ignore bad values */
+    if (new_jpeg_quality >=1 && new_jpeg_quality <= 100) {
+        if (mSecCamera->setJpegQuality(new_jpeg_quality) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setJpegQuality(quality(%d))", __func__, new_jpeg_quality);
+            ret = UNKNOWN_ERROR;
+        } else
+            mParameters.set(CameraParameters::KEY_JPEG_QUALITY, new_jpeg_quality);
+    }
+
+    // JPEG thumbnail size
+    int new_jpeg_thumbnail_width = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
+    int new_jpeg_thumbnail_height= params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
+    if (0 <= new_jpeg_thumbnail_width && 0 <= new_jpeg_thumbnail_height) {
+        if (mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __func__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, new_jpeg_thumbnail_width);
+            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, new_jpeg_thumbnail_height);
+        }
+    }
+
+    // JPEG thumbnail quality
+    int new_jpeg_thumbnail_quality = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+    LOGV("%s : new_jpeg_thumbnail_quality %d", __func__, new_jpeg_thumbnail_quality);
+    /* we ignore bad values */
+    if (new_jpeg_thumbnail_quality >=1 && new_jpeg_thumbnail_quality <= 100) {
+        if (mSecCamera->setJpegThumbnailQuality(new_jpeg_thumbnail_quality) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailQuality(quality(%d))",
+                                               __func__, new_jpeg_thumbnail_quality);
+            ret = UNKNOWN_ERROR;
+        } else
+            mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, new_jpeg_thumbnail_quality);
+    }
+
+    // frame rate
+    int new_frame_rate = params.getPreviewFrameRate();
+    /* ignore any fps request, we're determine fps automatically based
+     * on scene mode.  don't return an error because it causes CTS failure.
+     */
+    if (new_frame_rate != mParameters.getPreviewFrameRate()) {
+        if (mSecCamera->setFrameRate(new_frame_rate) < 0){
+            LOGE("ERR(%s):Fail on mSecCamera->setFrameRate(%d)", __func__, new_frame_rate);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.setPreviewFrameRate(new_frame_rate);
+        }
+     }
+
+    // rotation
+    int new_rotation = params.getInt(CameraParameters::KEY_ROTATION);
+    LOGV("%s : new_rotation %d", __func__, new_rotation);
+    if (0 <= new_rotation) {
+        LOGV("%s : set orientation:%d", __func__, new_rotation);
+        if (mSecCamera->setExifOrientationInfo(new_rotation) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_rotation);
+            ret = UNKNOWN_ERROR;
+        } else
+            mParameters.set(CameraParameters::KEY_ROTATION, new_rotation);
+    }
+
+    // brightness
+    int new_brightness = params.getInt("brightness");
+    int max_brightness = params.getInt("brightness-max");
+    int min_brightness = params.getInt("brightness-min");
+    LOGV("%s : new_brightness %d", __func__, new_brightness);
+    if ((min_brightness <= new_brightness) &&
+        (max_brightness >= new_brightness)) {
+        if (mSecCamera->setBrightness(new_brightness) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __func__, new_brightness);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set("brightness", new_brightness);
+        }
+    }
+
+    // saturation
+    int new_saturation = params.getInt("saturation");
+    int max_saturation = params.getInt("saturation-max");
+    int min_saturation = params.getInt("saturation-min");
+    LOGV("%s : new_saturation %d", __func__, new_saturation);
+    if ((min_saturation <= new_saturation) &&
+        (max_saturation >= new_saturation)) {
+        if (mSecCamera->setSaturation(new_saturation) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setSaturation(saturation(%d))", __func__, new_saturation);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set("saturation", new_saturation);
+        }
+    }
+
+    // sharpness
+    int new_sharpness = params.getInt("sharpness");
+    int max_sharpness = params.getInt("sharpness-max");
+    int min_sharpness = params.getInt("sharpness-min");
+    LOGV("%s : new_sharpness %d", __func__, new_sharpness);
+    if ((min_sharpness <= new_sharpness) &&
+        (max_sharpness >= new_sharpness)) {
+        if (mSecCamera->setSharpness(new_sharpness) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setSharpness(sharpness(%d))", __func__, new_sharpness);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set("sharpness", new_sharpness);
+        }
+    }
+
+    // hue
+    int new_hue = params.getInt("hue");
+    int max_hue = params.getInt("hue-max");
+    int min_hue = params.getInt("hue-min");
+    LOGV("%s : new_hue %d", __func__, new_hue);
+    if ((min_hue <= new_hue) &&
+        (max_hue >= new_hue)) {
+        if (mSecCamera->setHue(new_hue) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setHue(hue(%d))", __func__, new_hue);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set("hue", new_hue);
+        }
+    }
+
+    // exposure
+    int new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
+    int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
+    int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
+    LOGV("%s : new_exposure_compensation %d", __func__, new_exposure_compensation);
+    if ((min_exposure_compensation <= new_exposure_compensation) &&
+        (max_exposure_compensation >= new_exposure_compensation)) {
+        if (mSecCamera->setExposure(new_exposure_compensation) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setExposure(exposure(%d))", __func__, new_exposure_compensation);
+            ret = UNKNOWN_ERROR;
+        } else {
+            mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, new_exposure_compensation);
+        }
+    }
+
+    // ISO
+    const char *new_iso_str = params.get("iso");
+    LOGV("%s : new_iso_str %s", __func__, new_iso_str);
+    if (new_iso_str != NULL) {
+        int new_iso = -1;
+
+        if (!strcmp(new_iso_str, "auto")) {
+            if (Internal_is)
+                new_iso = IS_ISO_AUTO;
+            else
+                new_iso = ISO_AUTO;
+        } else if (!strcmp(new_iso_str, "50")) {
+            if (Internal_is)
+                new_iso = IS_ISO_50;
+            else
+                new_iso = ISO_50;
+        } else if (!strcmp(new_iso_str, "100")) {
+            if (Internal_is)
+                new_iso = IS_ISO_100;
+            else
+                new_iso = ISO_100;
+        } else if (!strcmp(new_iso_str, "200")) {
+            if (Internal_is)
+                new_iso = IS_ISO_200;
+            else
+                new_iso = ISO_200;
+        } else if (!strcmp(new_iso_str, "400")) {
+            if (Internal_is)
+                new_iso = IS_ISO_400;
+            else
+                new_iso = ISO_400;
+        } else if (!strcmp(new_iso_str, "800")) {
+            if (Internal_is)
+                new_iso = IS_ISO_800;
+            else
+                new_iso = ISO_800;
+        } else if (!strcmp(new_iso_str, "1600")) {
+            if (Internal_is)
+                new_iso = IS_ISO_1600;
+            else
+                new_iso = ISO_1600;
+        } else {
+            LOGE("ERR(%s):Invalid iso value(%s)", __func__, new_iso_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_iso) {
+            if (mSecCamera->setISO(new_iso) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setISO(iso(%d))", __func__, new_iso);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set("iso", new_iso_str);
+            }
+        }
+    }
+
+    // whitebalance
+    const char *new_white_str = params.get(CameraParameters::KEY_WHITE_BALANCE);
+    LOGV("%s : new_white_str %s", __func__, new_white_str);
+    if (new_white_str != NULL) {
+        int new_white = -1;
+
+        if (!strcmp(new_white_str, CameraParameters::WHITE_BALANCE_AUTO)) {
+            if (Internal_is)
+                new_white = IS_AWB_AUTO;
+            else
+                new_white = WHITE_BALANCE_AUTO;
+        } else if (!strcmp(new_white_str,
+                         CameraParameters::WHITE_BALANCE_DAYLIGHT)) {
+            if (Internal_is)
+                new_white = IS_AWB_DAYLIGHT;
+            else
+                new_white = WHITE_BALANCE_SUNNY;
+        } else if (!strcmp(new_white_str,
+                         CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT)) {
+            if (Internal_is)
+                new_white = IS_AWB_CLOUDY;
+            else
+                new_white = WHITE_BALANCE_CLOUDY;
+        } else if (!strcmp(new_white_str,
+                         CameraParameters::WHITE_BALANCE_FLUORESCENT)) {
+            if (Internal_is)
+                new_white = IS_AWB_FLUORESCENT;
+            else
+                new_white = WHITE_BALANCE_FLUORESCENT;
+        } else if (!strcmp(new_white_str,
+                         CameraParameters::WHITE_BALANCE_INCANDESCENT)) {
+            if (Internal_is)
+                new_white = IS_AWB_TUNGSTEN;
+            else
+                new_white = WHITE_BALANCE_TUNGSTEN;
+        } else {
+            LOGE("ERR(%s):Invalid white balance(%s)", __func__, new_white_str); //twilight, shade, warm_flourescent
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_white) {
+            if (mSecCamera->setWhiteBalance(new_white) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __func__, new_white);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set(CameraParameters::KEY_WHITE_BALANCE, new_white_str);
+            }
+        }
+    }
+
+    // Metering
+    const char *new_metering_str = params.get("metering");
+    LOGV("%s : new_metering_str %s", __func__, new_metering_str);
+    if (new_metering_str != NULL) {
+        int new_metering = -1;
+
+        if (!strcmp(new_metering_str, "center")) {
+            if (Internal_is)
+                new_metering = IS_METERING_AVERAGE;
+            else
+                new_metering = METERING_CENTER;
+        } else if (!strcmp(new_metering_str, "spot")) {
+            if (Internal_is)
+                new_metering = IS_METERING_SPOT;
+            else
+                new_metering = METERING_SPOT;
+        } else if (!strcmp(new_metering_str, "matrix")) {
+            if (Internal_is)
+                new_metering = IS_METERING_MATRIX;
+            else
+                new_metering = METERING_MATRIX;
+        } else {
+            LOGE("ERR(%s):Invalid metering value(%s)", __func__, new_metering_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_metering) {
+            if (mSecCamera->setMetering(new_metering) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setMetering(metering(%d))", __func__, new_metering);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set("metering", new_metering_str);
+            }
+        }
+    }
+
+    // AFC
+    const char *new_antibanding_str = params.get(CameraParameters::KEY_ANTIBANDING);
+    LOGV("%s : new_antibanding_str %s", __func__, new_antibanding_str);
+    if (new_antibanding_str != NULL) {
+        int new_antibanding = -1;
+
+        if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_AUTO)) {
+            if (Internal_is)
+                new_antibanding = IS_AFC_AUTO;
+            else
+                new_antibanding = ANTI_BANDING_AUTO;
+        } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_50HZ)) {
+            if (Internal_is)
+                new_antibanding = IS_AFC_MANUAL_50HZ;
+            else
+                new_antibanding = ANTI_BANDING_50HZ;
+        } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_60HZ)) {
+            if (Internal_is)
+                new_antibanding = IS_AFC_MANUAL_60HZ;
+            else
+                new_antibanding = ANTI_BANDING_60HZ;
+        } else if (!strcmp(new_antibanding_str, CameraParameters::ANTIBANDING_OFF)) {
+            if (Internal_is)
+                new_antibanding = IS_AFC_DISABLE;
+            else
+                new_antibanding = ANTI_BANDING_OFF;
+        } else {
+            LOGE("ERR(%s):Invalid antibanding value(%s)", __func__, new_antibanding_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_antibanding) {
+            if (mSecCamera->setAntiBanding(new_antibanding) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setAntiBanding(antibanding(%d))", __func__, new_antibanding);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set(CameraParameters::KEY_ANTIBANDING, new_antibanding_str);
+            }
+        }
+    }
+
+    // scene mode
+    const char *new_scene_mode_str = params.get(CameraParameters::KEY_SCENE_MODE);
+    const char *current_scene_mode_str = mParameters.get(CameraParameters::KEY_SCENE_MODE);
+
+    // fps range
+    int new_min_fps = 0;
+    int new_max_fps = 0;
+    int current_min_fps, current_max_fps;
+    params.getPreviewFpsRange(&new_min_fps, &new_max_fps);
+    mParameters.getPreviewFpsRange(&current_min_fps, &current_max_fps);
+    /* our fps range is determined by the sensor, reject any request
+     * that isn't exactly what we're already at.
+     * but the check is performed when requesting only changing fps range
+     */
+    if (new_scene_mode_str && current_scene_mode_str) {
+        if (!strcmp(new_scene_mode_str, current_scene_mode_str)) {
+            if ((new_min_fps != current_min_fps) || (new_max_fps != current_max_fps)) {
+                LOGW("%s : requested new_min_fps = %d, new_max_fps = %d not allowed",
+                        __func__, new_min_fps, new_max_fps);
+                LOGE("%s : current_min_fps = %d, current_max_fps = %d",
+                        __func__, current_min_fps, current_max_fps);
+                ret = UNKNOWN_ERROR;
+            }
+        }
+    } else {
+        /* Check basic validation if scene mode is different */
+        if ((new_min_fps > new_max_fps) ||
+            (new_min_fps < 0) || (new_max_fps < 0))
+        ret = UNKNOWN_ERROR;
+    }
+
+    if (new_scene_mode_str != NULL) {
+        int  new_scene_mode = -1;
+
+        const char *new_flash_mode_str = params.get(CameraParameters::KEY_FLASH_MODE);
+        const char *new_focus_mode_str;
+
+        new_focus_mode_str = params.get(CameraParameters::KEY_FOCUS_MODE);
+        // fps range is (15000,30000) by default.
+        mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(15000,30000)");
+        mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
+                "15000,30000");
+
+        if (!strcmp(new_scene_mode_str, CameraParameters::SCENE_MODE_AUTO)) {
+            new_scene_mode = SCENE_MODE_NONE;
+        } else {
+            // defaults for non-auto scene modes
+            if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) {
+                new_focus_mode_str = CameraParameters::FOCUS_MODE_AUTO;
+            }
+            new_flash_mode_str = CameraParameters::FLASH_MODE_OFF;
+
+            if (!strcmp(new_scene_mode_str,
+                       CameraParameters::SCENE_MODE_PORTRAIT)) {
+                new_scene_mode = SCENE_MODE_PORTRAIT;
+                new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_LANDSCAPE)) {
+                new_scene_mode = SCENE_MODE_LANDSCAPE;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_SPORTS)) {
+                new_scene_mode = SCENE_MODE_SPORTS;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_PARTY)) {
+                new_scene_mode = SCENE_MODE_PARTY_INDOOR;
+                new_flash_mode_str = CameraParameters::FLASH_MODE_AUTO;
+            } else if ((!strcmp(new_scene_mode_str,
+                                CameraParameters::SCENE_MODE_BEACH)) ||
+                        (!strcmp(new_scene_mode_str,
+                                 CameraParameters::SCENE_MODE_SNOW))) {
+                new_scene_mode = SCENE_MODE_BEACH_SNOW;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_SUNSET)) {
+                new_scene_mode = SCENE_MODE_SUNSET;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_NIGHT)) {
+                new_scene_mode = SCENE_MODE_NIGHTSHOT;
+                mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(4000,30000)");
+                mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
+                                "4000,30000");
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_FIREWORKS)) {
+                new_scene_mode = SCENE_MODE_FIREWORKS;
+            } else if (!strcmp(new_scene_mode_str,
+                               CameraParameters::SCENE_MODE_CANDLELIGHT)) {
+                new_scene_mode = SCENE_MODE_CANDLE_LIGHT;
+            } else {
+                LOGE("%s::unmatched scene_mode(%s)",
+                        __func__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto
+                ret = UNKNOWN_ERROR;
+            }
+        }
+
+        // focus mode
+        if (new_focus_mode_str != NULL) {
+            int  new_focus_mode = -1;
+
+            if (!strcmp(new_focus_mode_str,
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                new_focus_mode = FOCUS_MODE_AUTO;
+                mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
+                                BACK_CAMERA_AUTO_FOCUS_DISTANCES_STR);
+            } else if (!strcmp(new_focus_mode_str,
+                             CameraParameters::FOCUS_MODE_MACRO)) {
+                new_focus_mode = FOCUS_MODE_MACRO;
+                mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
+                                BACK_CAMERA_MACRO_FOCUS_DISTANCES_STR);
+            } else if (!strcmp(new_focus_mode_str,
+                             CameraParameters::FOCUS_MODE_INFINITY)) {
+                new_focus_mode = FOCUS_MODE_INFINITY;
+                mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES,
+                                BACK_CAMERA_INFINITY_FOCUS_DISTANCES_STR);
+            } else {
+                LOGE("%s::unmatched focus_mode(%s)", __func__, new_focus_mode_str);
+                ret = UNKNOWN_ERROR;
+            }
+
+            if (0 <= new_focus_mode) {
+                if (mSecCamera->setFocusMode(new_focus_mode) < 0) {
+                    LOGE("%s::mSecCamera->setFocusMode(%d) fail", __func__, new_focus_mode);
+                    ret = UNKNOWN_ERROR;
+                } else {
+                    mParameters.set(CameraParameters::KEY_FOCUS_MODE, new_focus_mode_str);
+                }
+            }
+        }
+
+        // flash..
+        if (new_flash_mode_str != NULL) {
+            int  new_flash_mode = -1;
+
+            if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_OFF))
+                new_flash_mode = FLASH_MODE_OFF;
+            else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_AUTO))
+                new_flash_mode = FLASH_MODE_AUTO;
+            else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_ON))
+                new_flash_mode = FLASH_MODE_ON;
+            else if (!strcmp(new_flash_mode_str, CameraParameters::FLASH_MODE_TORCH))
+                new_flash_mode = FLASH_MODE_TORCH;
+            else {
+                LOGE("%s::unmatched flash_mode(%s)", __func__, new_flash_mode_str); //red-eye
+                ret = UNKNOWN_ERROR;
+            }
+            if (0 <= new_flash_mode) {
+                if (mSecCamera->setFlashMode(new_flash_mode) < 0) {
+                    LOGE("%s::mSecCamera->setFlashMode(%d) fail", __func__, new_flash_mode);
+                    ret = UNKNOWN_ERROR;
+                } else {
+                    mParameters.set(CameraParameters::KEY_FLASH_MODE, new_flash_mode_str);
+                }
+            }
+        }
+
+        //  scene..
+        if (0 <= new_scene_mode) {
+            if (mSecCamera->setSceneMode(new_scene_mode) < 0) {
+                LOGE("%s::mSecCamera->setSceneMode(%d) fail", __func__, new_scene_mode);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set(CameraParameters::KEY_SCENE_MODE, new_scene_mode_str);
+            }
+        }
+    }
+
+    // image effect
+    const char *new_image_effect_str = params.get(CameraParameters::KEY_EFFECT);
+    if (new_image_effect_str != NULL) {
+
+        int  new_image_effect = -1;
+
+        if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NONE)) {
+            if (Internal_is)
+                new_image_effect = IS_IMAGE_EFFECT_DISABLE;
+            else
+                new_image_effect = IMAGE_EFFECT_NONE;
+        } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_MONO)) {
+            if (Internal_is)
+                new_image_effect = IS_IMAGE_EFFECT_MONOCHROME;
+            else
+                new_image_effect = IMAGE_EFFECT_BNW;
+        } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_SEPIA)) {
+            if (Internal_is)
+                new_image_effect = IS_IMAGE_EFFECT_SEPIA;
+            else
+                new_image_effect = IMAGE_EFFECT_SEPIA;
+        } else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_AQUA))
+            new_image_effect = IMAGE_EFFECT_AQUA;
+        else if (!strcmp(new_image_effect_str, CameraParameters::EFFECT_NEGATIVE)) {
+            if (Internal_is)
+                new_image_effect = IS_IMAGE_EFFECT_NEGATIVE_MONO;
+            else
+                LOGW("WARN(%s):Invalid effect value (%s)", __func__, new_image_effect_str);
+        } else {
+            //posterize, whiteboard, blackboard, solarize
+            LOGE("ERR(%s):Invalid effect(%s)", __func__, new_image_effect_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (new_image_effect >= 0) {
+            if (mSecCamera->setImageEffect(new_image_effect) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __func__, new_image_effect);
+                ret = UNKNOWN_ERROR;
+            } else {
+                const char *old_image_effect_str = mParameters.get(CameraParameters::KEY_EFFECT);
+
+                if (old_image_effect_str) {
+                    if (strcmp(old_image_effect_str, new_image_effect_str)) {
+                        setSkipFrame(EFFECT_SKIP_FRAME);
+                    }
+                }
+
+                mParameters.set(CameraParameters::KEY_EFFECT, new_image_effect_str);
+            }
+        }
+    }
+
+    //contrast
+    const char *new_contrast_str = params.get("contrast");
+    LOGV("%s : new_contrast_str %s", __func__, new_contrast_str);
+    if (new_contrast_str != NULL) {
+        int new_contrast = -1;
+
+        if (!strcmp(new_contrast_str, "auto")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_AUTO;
+            else
+                LOGW("WARN(%s):Invalid contrast value (%s)", __func__, new_contrast_str);
+        } else if (!strcmp(new_contrast_str, "-2")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_MINUS_2;
+            else
+                new_contrast = CONTRAST_MINUS_2;
+        } else if (!strcmp(new_contrast_str, "-1")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_MINUS_1;
+            else
+                new_contrast = CONTRAST_MINUS_1;
+        } else if (!strcmp(new_contrast_str, "0")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_DEFAULT;
+            else
+                new_contrast = CONTRAST_DEFAULT;
+        } else if (!strcmp(new_contrast_str, "1")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_PLUS_1;
+            else
+                new_contrast = CONTRAST_PLUS_1;
+        } else if (!strcmp(new_contrast_str, "2")) {
+            if (Internal_is)
+                new_contrast = IS_CONTRAST_PLUS_2;
+            else
+                new_contrast = CONTRAST_PLUS_2;
+        } else {
+            LOGE("ERR(%s):Invalid contrast value(%s)", __func__, new_contrast_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_contrast) {
+            if (mSecCamera->setContrast(new_contrast) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setContrast(contrast(%d))", __func__, new_contrast);
+                ret = UNKNOWN_ERROR;
+            } else {
+                mParameters.set("contrast", new_contrast_str);
+            }
+        }
+    }
+
+    //WDR
+    int new_wdr = params.getInt("wdr");
+    LOGV("%s : new_wdr %d", __func__, new_wdr);
+
+    if (0 <= new_wdr) {
+        if (mSecCamera->setWDR(new_wdr) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_wdr);
+            ret = UNKNOWN_ERROR;
+        }
+    }
+
+    //anti shake
+    int new_anti_shake = mInternalParameters.getInt("anti-shake");
+
+    if (0 <= new_anti_shake) {
+        if (mSecCamera->setAntiShake(new_anti_shake) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __func__, new_anti_shake);
+            ret = UNKNOWN_ERROR;
+        }
+    }
+
+    // gps latitude
+    const char *new_gps_latitude_str = params.get(CameraParameters::KEY_GPS_LATITUDE);
+    if (mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) {
+        LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __func__, new_gps_latitude_str);
+        ret = UNKNOWN_ERROR;
+    } else {
+        if (new_gps_latitude_str) {
+            mParameters.set(CameraParameters::KEY_GPS_LATITUDE, new_gps_latitude_str);
+        } else {
+            mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
+        }
+    }
+
+    // gps longitude
+    const char *new_gps_longitude_str = params.get(CameraParameters::KEY_GPS_LONGITUDE);
+
+    if (mSecCamera->setGPSLongitude(new_gps_longitude_str) < 0) {
+        LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __func__, new_gps_longitude_str);
+        ret = UNKNOWN_ERROR;
+    } else {
+        if (new_gps_longitude_str) {
+            mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, new_gps_longitude_str);
+        } else {
+            mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
+        }
+    }
+
+    // gps altitude
+    const char *new_gps_altitude_str = params.get(CameraParameters::KEY_GPS_ALTITUDE);
+
+    if (mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) {
+        LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __func__, new_gps_altitude_str);
+        ret = UNKNOWN_ERROR;
+    } else {
+        if (new_gps_altitude_str) {
+            mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, new_gps_altitude_str);
+        } else {
+            mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
+        }
+    }
+
+    // gps timestamp
+    const char *new_gps_timestamp_str = params.get(CameraParameters::KEY_GPS_TIMESTAMP);
+
+    if (mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) {
+        LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __func__, new_gps_timestamp_str);
+        ret = UNKNOWN_ERROR;
+    } else {
+        if (new_gps_timestamp_str) {
+            mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, new_gps_timestamp_str);
+        } else {
+            mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
+        }
+    }
+
+    // gps processing method
+    const char *new_gps_processing_method_str = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+
+    if (mSecCamera->setGPSProcessingMethod(new_gps_processing_method_str) < 0) {
+        LOGE("%s::mSecCamera->setGPSProcessingMethod(%s) fail", __func__, new_gps_processing_method_str);
+        ret = UNKNOWN_ERROR;
+    } else {
+        if (new_gps_processing_method_str) {
+            mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, new_gps_processing_method_str);
+        } else {
+            mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
+        }
+    }
+
+    // Recording size
+    int new_recording_width  = 0;
+    int new_recording_height = 0;
+    params.getVideoSize(&new_recording_width, &new_recording_height);
+    LOGV("new_recording_width (%d) new_recording_height (%d)",
+            new_recording_width, new_recording_height);
+
+    int current_recording_width, current_recording_height;
+    mSecCamera->getRecordingSize(&current_recording_width, &current_recording_height);
+    LOGV("current_recording_width (%d) current_recording_height (%d)",
+            current_recording_width, current_recording_height);
+
+    if (0 < new_recording_width && 0 < new_recording_height) {
+          if (current_recording_width != new_recording_width ||
+              current_recording_height != new_recording_height) {
+            if (mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) {
+                LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))",
+                        __func__, new_recording_width, new_recording_height);
+                ret = UNKNOWN_ERROR;
+            } else {
+                if (Internal_is && mPreviewWindow && mPreviewRunning) {
+                    mSecCamera->setRecording(1);
+                    stopPreview();
+                    startPreview();
+                    mSecCamera->setRecording(0);
+                }
+            }
+        }
+        mParameters.setVideoSize(new_recording_width, new_recording_height);
+    } else {
+        if (mSecCamera->setRecordingSize(new_preview_width, new_preview_height) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))",
+                    __func__, new_preview_width, new_preview_height);
+            ret = UNKNOWN_ERROR;
+        }
+    }
+
+    //gamma
+    const char *new_gamma_str = mInternalParameters.get("video_recording_gamma");
+
+    if (new_gamma_str != NULL) {
+        int new_gamma = -1;
+        if (!strcmp(new_gamma_str, "off"))
+            new_gamma = GAMMA_OFF;
+        else if (!strcmp(new_gamma_str, "on"))
+            new_gamma = GAMMA_ON;
+        else {
+            LOGE("%s::unmatched gamma(%s)", __func__, new_gamma_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_gamma) {
+            if (mSecCamera->setGamma(new_gamma) < 0) {
+                LOGE("%s::mSecCamera->setGamma(%d) fail", __func__, new_gamma);
+                ret = UNKNOWN_ERROR;
+            }
+        }
+    }
+
+    //slow ae
+    const char *new_slow_ae_str = mInternalParameters.get("slow_ae");
+
+    if (new_slow_ae_str != NULL) {
+        int new_slow_ae = -1;
+
+        if (!strcmp(new_slow_ae_str, "off"))
+            new_slow_ae = SLOW_AE_OFF;
+        else if (!strcmp(new_slow_ae_str, "on"))
+            new_slow_ae = SLOW_AE_ON;
+        else {
+            LOGE("%s::unmatched slow_ae(%s)", __func__, new_slow_ae_str);
+            ret = UNKNOWN_ERROR;
+        }
+
+        if (0 <= new_slow_ae) {
+            if (mSecCamera->setSlowAE(new_slow_ae) < 0) {
+                LOGE("%s::mSecCamera->setSlowAE(%d) fail", __func__, new_slow_ae);
+                ret = UNKNOWN_ERROR;
+            }
+        }
+    }
+
+    /*Camcorder fix fps*/
+    int new_sensor_mode = mInternalParameters.getInt("cam_mode");
+
+    if (0 <= new_sensor_mode) {
+        if (mSecCamera->setSensorMode(new_sensor_mode) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __func__, new_sensor_mode);
+            ret = UNKNOWN_ERROR;
+        }
+    } else {
+        new_sensor_mode=0;
+    }
+
+    /*Shot mode*/
+    int new_shot_mode = mInternalParameters.getInt("shot_mode");
+
+    if (0 <= new_shot_mode) {
+        if (mSecCamera->setShotMode(new_shot_mode) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __func__, new_shot_mode);
+            ret = UNKNOWN_ERROR;
+        }
+    } else {
+        new_shot_mode=0;
+    }
+
+    // chk_dataline
+    int new_dataline = mInternalParameters.getInt("chk_dataline");
+
+    if (0 <= new_dataline) {
+        if (mSecCamera->setDataLineCheck(new_dataline) < 0) {
+            LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __func__, new_dataline);
+            ret = UNKNOWN_ERROR;
+        }
+    }
+    LOGV("%s return ret = %d", __func__, ret);
+#endif
+
+    return ret;
+}
+
+CameraParameters CameraHardwareSec::getParameters() const
+{
+    LOGV("%s :", __func__);
+    return mParameters;
+}
+
+status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2)
+{
+    return BAD_VALUE;
+}
+
+void CameraHardwareSec::release()
+{
+    LOGV("%s", __func__);
+
+    /* shut down any threads we have that might be running.  do it here
+     * instead of the destructor.  we're guaranteed to be on another thread
+     * than the ones below.  if we used the destructor, since the threads
+     * have a reference to this object, we could wind up trying to wait
+     * for ourself to exit, which is a deadlock.
+     */
+    if (mPreviewThread != NULL) {
+        /* this thread is normally already in it's threadLoop but blocked
+         * on the condition variable or running.  signal it so it wakes
+         * up and can exit.
+         */
+        mPreviewThread->requestExit();
+        mExitPreviewThread = true;
+        mPreviewRunning = true; /* let it run so it can exit */
+        mPreviewCondition.signal();
+        mPreviewThread->requestExitAndWait();
+        mPreviewThread.clear();
+    }
+    if (mAutoFocusThread != NULL) {
+        /* this thread is normally already in it's threadLoop but blocked
+         * on the condition variable.  signal it so it wakes up and can exit.
+         */
+        mFocusLock.lock();
+        mAutoFocusThread->requestExit();
+        mExitAutoFocusThread = true;
+        mFocusCondition.signal();
+        mFocusLock.unlock();
+        mAutoFocusThread->requestExitAndWait();
+        mAutoFocusThread.clear();
+    }
+    if (mPictureThread != NULL) {
+        mPictureThread->requestExitAndWait();
+        mPictureThread.clear();
+    }
+
+    if (mRawHeap) {
+        mRawHeap->release(mRawHeap);
+        mRawHeap = 0;
+    }
+    if (mPreviewHeap) {
+        mPreviewHeap->release(mPreviewHeap);
+        mPreviewHeap = 0;
+    }
+    for(int i = 0; i < BUFFER_COUNT_FOR_ARRAY; i++) {
+        if (mRecordHeap[i]) {
+            mRecordHeap[i]->release(mRecordHeap[i]);
+            mRecordHeap[i] = 0;
+        }
+    }
+
+     /* close after all the heaps are cleared since those
+     * could have dup'd our file descriptor.
+     */
+    mSecCamera->DestroyCamera();
+}
+
+static CameraInfo sCameraInfo[] = {
+    {
+        CAMERA_FACING_BACK,
+        0,  /* orientation */
+    },
+    {
+        CAMERA_FACING_FRONT,
+        0,  /* orientation */
+    }
+};
+
+status_t CameraHardwareSec::storeMetaDataInBuffers(bool enable)
+{
+    if (!enable) {
+        LOGE("Non-metadata buffer mode is not supported!");
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+/** Close this device */
+
+static camera_device_t *g_cam_device;
+
+static int HAL_camera_device_close(struct hw_device_t* device)
+{
+    LOGI("%s", __func__);
+    if (device) {
+        camera_device_t *cam_device = (camera_device_t *)device;
+        delete static_cast<CameraHardwareSec *>(cam_device->priv);
+        free(cam_device);
+        g_cam_device = 0;
+    }
+    return 0;
+}
+
+static inline CameraHardwareSec *obj(struct camera_device *dev)
+{
+    return reinterpret_cast<CameraHardwareSec *>(dev->priv);
+}
+
+/** Set the preview_stream_ops to which preview frames are sent */
+static int HAL_camera_device_set_preview_window(struct camera_device *dev,
+                                                struct preview_stream_ops *buf)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->setPreviewWindow(buf);
+}
+
+/** Set the notification and data callbacks */
+static void HAL_camera_device_set_callbacks(struct camera_device *dev,
+        camera_notify_callback notify_cb,
+        camera_data_callback data_cb,
+        camera_data_timestamp_callback data_cb_timestamp,
+        camera_request_memory get_memory,
+        void* user)
+{
+    LOGV("%s", __func__);
+    obj(dev)->setCallbacks(notify_cb, data_cb, data_cb_timestamp,
+                           get_memory,
+                           user);
+}
+
+/**
+ * The following three functions all take a msg_type, which is a bitmask of
+ * the messages defined in include/ui/Camera.h
+ */
+
+/**
+ * Enable a message, or set of messages.
+ */
+static void HAL_camera_device_enable_msg_type(struct camera_device *dev, int32_t msg_type)
+{
+    LOGV("%s", __func__);
+    obj(dev)->enableMsgType(msg_type);
+}
+
+/**
+ * Disable a message, or a set of messages.
+ *
+ * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera
+ * HAL should not rely on its client to call releaseRecordingFrame() to
+ * release video recording frames sent out by the cameral HAL before and
+ * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL
+ * clients must not modify/access any video recording frame after calling
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME).
+ */
+static void HAL_camera_device_disable_msg_type(struct camera_device *dev, int32_t msg_type)
+{
+    LOGV("%s", __func__);
+    obj(dev)->disableMsgType(msg_type);
+}
+
+/**
+ * Query whether a message, or a set of messages, is enabled.  Note that
+ * this is operates as an AND, if any of the messages queried are off, this
+ * will return false.
+ */
+static int HAL_camera_device_msg_type_enabled(struct camera_device *dev, int32_t msg_type)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->msgTypeEnabled(msg_type);
+}
+
+/**
+ * Start preview mode.
+ */
+static int HAL_camera_device_start_preview(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->startPreview();
+}
+
+/**
+ * Stop a previously started preview.
+ */
+static void HAL_camera_device_stop_preview(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    obj(dev)->stopPreview();
+}
+
+/**
+ * Returns true if preview is enabled.
+ */
+static int HAL_camera_device_preview_enabled(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->previewEnabled();
+}
+
+/**
+ * Request the camera HAL to store meta data or real YUV data in the video
+ * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If
+ * it is not called, the default camera HAL behavior is to store real YUV
+ * data in the video buffers.
+ *
+ * This method should be called before startRecording() in order to be
+ * effective.
+ *
+ * If meta data is stored in the video buffers, it is up to the receiver of
+ * the video buffers to interpret the contents and to find the actual frame
+ * data with the help of the meta data in the buffer. How this is done is
+ * outside of the scope of this method.
+ *
+ * Some camera HALs may not support storing meta data in the video buffers,
+ * but all camera HALs should support storing real YUV data in the video
+ * buffers. If the camera HAL does not support storing the meta data in the
+ * video buffers when it is requested to do do, INVALID_OPERATION must be
+ * returned. It is very useful for the camera HAL to pass meta data rather
+ * than the actual frame data directly to the video encoder, since the
+ * amount of the uncompressed frame data can be very large if video size is
+ * large.
+ *
+ * @param enable if true to instruct the camera HAL to store
+ *      meta data in the video buffers; false to instruct
+ *      the camera HAL to store real YUV data in the video
+ *      buffers.
+ *
+ * @return OK on success.
+ */
+static int HAL_camera_device_store_meta_data_in_buffers(struct camera_device *dev, int enable)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->storeMetaDataInBuffers(enable);
+}
+
+/**
+ * Start record mode. When a record image is available, a
+ * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding
+ * frame. Every record frame must be released by a camera HAL client via
+ * releaseRecordingFrame() before the client calls
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
+ * responsibility to manage the life-cycle of the video recording frames,
+ * and the client must not modify/access any video recording frames.
+ */
+static int HAL_camera_device_start_recording(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->startRecording();
+}
+
+/**
+ * Stop a previously started recording.
+ */
+static void HAL_camera_device_stop_recording(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    obj(dev)->stopRecording();
+}
+
+/**
+ * Returns true if recording is enabled.
+ */
+static int HAL_camera_device_recording_enabled(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->recordingEnabled();
+}
+
+/**
+ * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+ *
+ * It is camera HAL client's responsibility to release video recording
+ * frames sent out by the camera HAL before the camera HAL receives a call
+ * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to
+ * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's
+ * responsibility to manage the life-cycle of the video recording frames.
+ */
+static void HAL_camera_device_release_recording_frame(struct camera_device *dev,
+                                const void *opaque)
+{
+    LOGV("%s", __func__);
+    obj(dev)->releaseRecordingFrame(opaque);
+}
+
+/**
+ * Start auto focus, the notification callback routine is called with
+ * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be
+ * called again if another auto focus is needed.
+ */
+static int HAL_camera_device_auto_focus(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->autoFocus();
+}
+
+/**
+ * Cancels auto-focus function. If the auto-focus is still in progress,
+ * this function will cancel it. Whether the auto-focus is in progress or
+ * not, this function will return the focus position to the default.  If
+ * the camera does not support auto-focus, this is a no-op.
+ */
+static int HAL_camera_device_cancel_auto_focus(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->cancelAutoFocus();
+}
+
+/**
+ * Take a picture.
+ */
+static int HAL_camera_device_take_picture(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->takePicture();
+}
+
+/**
+ * Cancel a picture that was started with takePicture. Calling this method
+ * when no picture is being taken is a no-op.
+ */
+static int HAL_camera_device_cancel_picture(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->cancelPicture();
+}
+
+/**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported.
+ */
+static int HAL_camera_device_set_parameters(struct camera_device *dev,
+                                            const char *parms)
+{
+    LOGV("%s", __func__);
+    String8 str(parms);
+    CameraParameters p(str);
+    return obj(dev)->setParameters(p);
+}
+
+/** Return the camera parameters. */
+char *HAL_camera_device_get_parameters(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    String8 str;
+    CameraParameters parms = obj(dev)->getParameters();
+    str = parms.flatten();
+    return strdup(str.string());
+}
+
+static void HAL_camera_device_put_parameters(struct camera_device *dev, char *parms)
+{
+    LOGV("%s", __func__);
+    free(parms);
+}
+
+/**
+ * Send command to camera driver.
+ */
+static int HAL_camera_device_send_command(struct camera_device *dev,
+                    int32_t cmd, int32_t arg1, int32_t arg2)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->sendCommand(cmd, arg1, arg2);
+}
+
+/**
+ * Release the hardware resources owned by this object.  Note that this is
+ * *not* done in the destructor.
+ */
+static void HAL_camera_device_release(struct camera_device *dev)
+{
+    LOGV("%s", __func__);
+    obj(dev)->release();
+}
+
+/**
+ * Dump state of the camera hardware
+ */
+static int HAL_camera_device_dump(struct camera_device *dev, int fd)
+{
+    LOGV("%s", __func__);
+    return obj(dev)->dump(fd);
+}
+
+static int HAL_getNumberOfCameras()
+{
+    LOGV("%s", __func__);
+    return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
+}
+
+static int HAL_getCameraInfo(int cameraId, struct camera_info *cameraInfo)
+{
+    LOGV("%s", __func__);
+    memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
+    return 0;
+}
+
+#define SET_METHOD(m) m : HAL_camera_device_##m
+
+static camera_device_ops_t camera_device_ops = {
+        SET_METHOD(set_preview_window),
+        SET_METHOD(set_callbacks),
+        SET_METHOD(enable_msg_type),
+        SET_METHOD(disable_msg_type),
+        SET_METHOD(msg_type_enabled),
+        SET_METHOD(start_preview),
+        SET_METHOD(stop_preview),
+        SET_METHOD(preview_enabled),
+        SET_METHOD(store_meta_data_in_buffers),
+        SET_METHOD(start_recording),
+        SET_METHOD(stop_recording),
+        SET_METHOD(recording_enabled),
+        SET_METHOD(release_recording_frame),
+        SET_METHOD(auto_focus),
+        SET_METHOD(cancel_auto_focus),
+        SET_METHOD(take_picture),
+        SET_METHOD(cancel_picture),
+        SET_METHOD(set_parameters),
+        SET_METHOD(get_parameters),
+        SET_METHOD(put_parameters),
+        SET_METHOD(send_command),
+        SET_METHOD(release),
+        SET_METHOD(dump),
+};
+
+#undef SET_METHOD
+
+static int HAL_camera_device_open(const struct hw_module_t* module,
+                                  const char *id,
+                                  struct hw_device_t** device)
+{
+    LOGV("%s", __func__);
+
+    int cameraId = atoi(id);
+    if (cameraId < 0 || cameraId >= HAL_getNumberOfCameras()) {
+        LOGE("Invalid camera ID %s", id);
+        return -EINVAL;
+    }
+
+    if (g_cam_device) {
+        if (obj(g_cam_device)->getCameraId() == cameraId) {
+            LOGV("returning existing camera ID %s", id);
+            goto done;
+        } else {
+            LOGE("Cannot open camera %d. camera %d is already running!",
+                    cameraId, obj(g_cam_device)->getCameraId());
+            return -ENOSYS;
+        }
+    }
+
+    g_cam_device = (camera_device_t *)malloc(sizeof(camera_device_t));
+    if (!g_cam_device)
+        return -ENOMEM;
+
+    g_cam_device->common.tag     = HARDWARE_DEVICE_TAG;
+    g_cam_device->common.version = 1;
+    g_cam_device->common.module  = const_cast<hw_module_t *>(module);
+    g_cam_device->common.close   = HAL_camera_device_close;
+
+    g_cam_device->ops = &camera_device_ops;
+
+    LOGI("%s: open camera %s", __func__, id);
+
+    g_cam_device->priv = new CameraHardwareSec(cameraId, g_cam_device);
+
+done:
+    *device = (hw_device_t *)g_cam_device;
+    LOGI("%s: opened camera %s (%p)", __func__, id, *device);
+    return 0;
+}
+
+static hw_module_methods_t camera_module_methods = {
+            open : HAL_camera_device_open
+};
+
+extern "C" {
+    struct camera_module HAL_MODULE_INFO_SYM = {
+      common : {
+          tag           : HARDWARE_MODULE_TAG,
+          version_major : 1,
+          version_minor : 0,
+          id            : CAMERA_HARDWARE_MODULE_ID,
+          name          : "orion camera HAL",
+          author        : "Samsung Corporation",
+          methods       : &camera_module_methods,
+      },
+      get_number_of_cameras : HAL_getNumberOfCameras,
+      get_camera_info       : HAL_getCameraInfo
+    };
+}
+
+}; // namespace android
diff --git a/exynos5/hal/libcamera/SecCameraHWInterface.h b/exynos5/hal/libcamera/SecCameraHWInterface.h
new file mode 100644
index 0000000..6be8ae2
--- /dev/null
+++ b/exynos5/hal/libcamera/SecCameraHWInterface.h
@@ -0,0 +1,219 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+** Copyright 2010, Samsung Electronics Co. LTD
+**
+** 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 ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H
+
+#include "SecCamera.h"
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <hardware/camera.h>
+#include <hardware/gralloc.h>
+#include <camera/CameraParameters.h>
+#include <binder/MemoryHeapBaseIon.h>
+#include <sec_utils_v4l2.h>
+
+#include "gralloc_priv.h"
+
+#define  BUFFER_COUNT_FOR_GRALLOC (MAX_BUFFERS + 4)
+#define  BUFFER_COUNT_FOR_ARRAY (MAX_BUFFERS)
+
+namespace android {
+    class CameraHardwareSec : public virtual RefBase {
+public:
+    virtual void        setCallbacks(camera_notify_callback notify_cb,
+                                     camera_data_callback data_cb,
+                                     camera_data_timestamp_callback data_cb_timestamp,
+                                     camera_request_memory get_memory,
+                                     void *user);
+
+    virtual void        enableMsgType(int32_t msgType);
+    virtual void        disableMsgType(int32_t msgType);
+    virtual bool        msgTypeEnabled(int32_t msgType);
+
+    virtual status_t    startPreview();
+    virtual void        stopPreview();
+    virtual bool        previewEnabled();
+
+    virtual status_t    startRecording();
+    virtual void        stopRecording();
+    virtual bool        recordingEnabled();
+    virtual void        releaseRecordingFrame(const void *opaque);
+
+    virtual status_t    autoFocus();
+    virtual status_t    cancelAutoFocus();
+    virtual status_t    takePicture();
+    virtual status_t    cancelPicture();
+    virtual status_t    dump(int fd) const;
+    virtual status_t    setParameters(const CameraParameters& params);
+    virtual CameraParameters  getParameters() const;
+    virtual status_t    sendCommand(int32_t command, int32_t arg1, int32_t arg2);
+    virtual status_t    setPreviewWindow(preview_stream_ops *w);
+    virtual status_t    storeMetaDataInBuffers(bool enable);
+    virtual void        release();
+
+    inline  int         getCameraId() const;
+
+    CameraHardwareSec(int cameraId, camera_device_t *dev);
+    virtual             ~CameraHardwareSec();
+private:
+    status_t    startPreviewInternal();
+    void stopPreviewInternal();
+
+    class PreviewThread : public Thread {
+        CameraHardwareSec *mHardware;
+    public:
+        PreviewThread(CameraHardwareSec *hw):
+        Thread(false),
+        mHardware(hw) { }
+        virtual void onFirstRef() {
+            run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual bool threadLoop() {
+            mHardware->previewThreadWrapper();
+            return false;
+        }
+    };
+
+    class PictureThread : public Thread {
+        CameraHardwareSec *mHardware;
+    public:
+        PictureThread(CameraHardwareSec *hw):
+        Thread(false),
+        mHardware(hw) { }
+        virtual bool threadLoop() {
+            mHardware->pictureThread();
+            mHardware->mSecCamera->endSnapshot();
+            return false;
+        }
+    };
+
+    class AutoFocusThread : public Thread {
+        CameraHardwareSec *mHardware;
+    public:
+        AutoFocusThread(CameraHardwareSec *hw): Thread(false), mHardware(hw) { }
+        virtual void onFirstRef() {
+            run("CameraAutoFocusThread", PRIORITY_DEFAULT);
+        }
+        virtual bool threadLoop() {
+            mHardware->autoFocusThread();
+            return true;
+        }
+    };
+
+            void        initDefaultParameters(int cameraId);
+            void        initHeapLocked();
+
+    sp<PreviewThread>   mPreviewThread;
+            int         previewThread();
+            int         previewThreadWrapper();
+
+    sp<AutoFocusThread> mAutoFocusThread;
+            int         autoFocusThread();
+
+    sp<PictureThread>   mPictureThread;
+            int         pictureThread();
+            bool        mCaptureInProgress;
+
+            int         save_jpeg(unsigned char *real_jpeg, int jpeg_size);
+            void        save_postview(const char *fname, uint8_t *buf,
+                                        uint32_t size);
+            int         decodeInterleaveData(unsigned char *pInterleaveData,
+                                                int interleaveDataSize,
+                                                int yuvWidth,
+                                                int yuvHeight,
+                                                int *pJpegSize,
+                                                void *pJpegData,
+                                                void *pYuvData);
+            bool        YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight);
+            bool        scaleDownYuv422(char *srcBuf, uint32_t srcWidth,
+                                        uint32_t srcHight, char *dstBuf,
+                                        uint32_t dstWidth, uint32_t dstHight);
+
+            bool        CheckVideoStartMarker(unsigned char *pBuf);
+            bool        CheckEOIMarker(unsigned char *pBuf);
+            bool        FindEOIMarkerInJPEG(unsigned char *pBuf,
+                                            int dwBufSize, int *pnJPEGsize);
+            bool        SplitFrame(unsigned char *pFrame, int dwSize,
+                                   int dwJPEGLineLength, int dwVideoLineLength,
+                                   int dwVideoHeight, void *pJPEG,
+                                   int *pdwJPEGSize, void *pVideo,
+                                   int *pdwVideoSize);
+            void        setSkipFrame(int frame);
+            bool        isSupportedPreviewSize(const int width,
+                                               const int height) const;
+    /* used by auto focus thread to block until it's told to run */
+    mutable Mutex       mFocusLock;
+    mutable Condition   mFocusCondition;
+            bool        mExitAutoFocusThread;
+
+    /* used by preview thread to block until it's told to run */
+    mutable Mutex       mPreviewLock;
+    mutable Condition   mPreviewCondition;
+    mutable Condition   mPreviewStoppedCondition;
+            bool        mPreviewRunning;
+            bool        mPreviewStartDeferred;
+            bool        mExitPreviewThread;
+
+            preview_stream_ops *mPreviewWindow;
+
+    /* used to guard threading state */
+    mutable Mutex       mStateLock;
+
+    CameraParameters    mParameters;
+    CameraParameters    mInternalParameters;
+
+    int                 mFrameSizeDelta;
+    camera_memory_t     *mPreviewHeap;
+    camera_memory_t     *mRawHeap;
+    camera_memory_t     *mRecordHeap[BUFFER_COUNT_FOR_ARRAY];
+
+    buffer_handle_t *mBufferHandle[BUFFER_COUNT_FOR_ARRAY];
+    int mStride[BUFFER_COUNT_FOR_ARRAY];
+
+
+    SecCamera           *mSecCamera;
+            const __u8  *mCameraSensorName;
+
+    mutable Mutex       mSkipFrameLock;
+            int         mSkipFrame;
+
+    camera_notify_callback     mNotifyCb;
+    camera_data_callback       mDataCb;
+    camera_data_timestamp_callback mDataCbTimestamp;
+    camera_request_memory      mGetMemoryCb;
+    void   *mCallbackCookie;
+
+            int32_t     mMsgEnabled;
+
+            bool        mRecordRunning;
+    mutable Mutex       mRecordLock;
+            int         mPostViewWidth;
+            int         mPostViewHeight;
+            int         mPostViewSize;
+
+            Vector<Size> mSupportedPreviewSizes;
+
+    camera_device_t *mHalDevice;
+    static gralloc_module_t const* mGrallocHal;
+};
+
+}; // namespace android
+
+#endif
diff --git a/exynos5/hal/libcamera/mediactl.cpp b/exynos5/hal/libcamera/mediactl.cpp
new file mode 100644
index 0000000..468acc4
--- /dev/null
+++ b/exynos5/hal/libcamera/mediactl.cpp
@@ -0,0 +1,668 @@
+/*
+ * Media controller interface library
+ *
+ * Copyright (C) 2010-2011 Ideas on board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//#include "config.h"
+#define LOG_NDEBUG 0
+#define LOG_TAG "Mediactl"
+
+#include <utils/Log.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include <poll.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <linux/videodev2.h>
+#include <media.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+
+#include "mediactl.h"
+
+#define KF_MSG                              0x1
+#define KF_ANY                              0x2
+
+#define perror_exit(cond, func) \
+    if (cond) { \
+        fprintf(stderr, "[%s:%d]: ", __func__, __LINE__);\
+        perror(func);\
+        exit(EXIT_FAILURE);\
+    }
+
+struct media_pad *media_entity_remote_source(struct media_pad *pad)
+{
+    unsigned int i;
+
+    if (!(pad->flags & MEDIA_PAD_FL_SINK))
+        return NULL;
+
+    for (i = 0; i < pad->entity->num_links; ++i) {
+        struct media_link *link = &pad->entity->links[i];
+
+        if (!(link->flags & MEDIA_LNK_FL_ENABLED))
+            continue;
+
+        if (link->sink == pad)
+            return link->source;
+    }
+
+    return NULL;
+}
+
+struct media_entity *media_get_entity_by_name(struct media_device *media,
+                          const char *name, size_t length)
+{
+    unsigned int i;
+        struct media_entity *entity;
+        entity = (struct media_entity*)calloc(1,  sizeof(struct media_entity));
+    for (i = 0; i < media->entities_count; ++i) {
+        entity = &media->entities[i];
+
+        if (strncmp(entity->info.name, name, length) == 0)
+            return entity;
+    }
+
+    return NULL;
+}
+
+struct media_entity *media_get_entity_by_id(struct media_device *media,
+                        __u32 id)
+{
+    unsigned int i;
+
+    for (i = 0; i < media->entities_count; ++i) {
+        struct media_entity *entity = &media->entities[i];
+
+        if (entity->info.id == id)
+            return entity;
+    }
+
+    return NULL;
+}
+
+int media_setup_link(struct media_device *media,
+             struct media_pad *source,
+             struct media_pad *sink,
+             __u32 flags)
+{
+    struct media_link *link;
+    struct media_link_desc ulink;
+    unsigned int i;
+    int ret;
+
+    for (i = 0; i < source->entity->num_links; i++) {
+        link = &source->entity->links[i];
+
+        if (link->source->entity == source->entity &&
+            link->source->index == source->index &&
+            link->sink->entity == sink->entity &&
+            link->sink->index == sink->index)
+            break;
+    }
+
+    if (i == source->entity->num_links) {
+        LOGE("%s: Link not found", __func__);
+        return -ENOENT;
+    }
+
+    /* source pad */
+    ulink.source.entity = source->entity->info.id;
+    ulink.source.index = source->index;
+    ulink.source.flags = MEDIA_PAD_FL_SOURCE;
+
+    /* sink pad */
+    ulink.sink.entity = sink->entity->info.id;
+    ulink.sink.index = sink->index;
+    ulink.sink.flags = MEDIA_PAD_FL_SINK;
+
+    ulink.flags = flags | (link->flags & MEDIA_LNK_FL_IMMUTABLE);
+
+    ret = ioctl(media->fd, MEDIA_IOC_SETUP_LINK, &ulink);
+    if (ret == -1) {
+        LOGE("%s: Unable to setup link (%s)",
+              __func__, strerror(errno));
+        return -errno;
+    }
+
+    link->flags = ulink.flags;
+    link->twin->flags = ulink.flags;
+    return 0;
+}
+
+int media_reset_links(struct media_device *media)
+{
+    unsigned int i, j;
+    int ret;
+
+    for (i = 0; i < media->entities_count; ++i) {
+        struct media_entity *entity = &media->entities[i];
+
+        for (j = 0; j < entity->num_links; j++) {
+            struct media_link *link = &entity->links[j];
+
+            if (link->flags & MEDIA_LNK_FL_IMMUTABLE ||
+                link->source->entity != entity)
+                continue;
+
+            ret = media_setup_link(media, link->source, link->sink,
+                           link->flags & ~MEDIA_LNK_FL_ENABLED);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
+    return 0;
+}
+
+static struct media_link *media_entity_add_link(struct media_entity *entity)
+{
+    if (entity->num_links >= entity->max_links) {
+        struct media_link *links = entity->links;
+        unsigned int max_links = entity->max_links * 2;
+        unsigned int i;
+
+        links = (struct media_link*)realloc(links, max_links * sizeof *links);
+        if (links == NULL)
+            return NULL;
+
+        for (i = 0; i < entity->num_links; ++i)
+            links[i].twin->twin = &links[i];
+
+        entity->max_links = max_links;
+        entity->links = links;
+    }
+
+    return &entity->links[entity->num_links++];
+}
+
+static int media_enum_links(struct media_device *media)
+{
+    LOGV("%s: start", __func__);
+    __u32 id;
+    int ret = 0;
+
+    for (id = 1; id <= media->entities_count; id++) {
+        struct media_entity *entity = &media->entities[id - 1];
+        struct media_links_enum links;
+        unsigned int i;
+
+        links.entity = entity->info.id;
+        links.pads = (struct media_pad_desc*)malloc(entity->info.pads * sizeof(struct media_pad_desc));
+        links.links = (struct media_link_desc*)malloc(entity->info.links * sizeof(struct media_link_desc));
+
+        if (ioctl(media->fd, MEDIA_IOC_ENUM_LINKS, &links) < 0) {
+            LOGE(
+                  "%s: Unable to enumerate pads and links (%s).",
+                  __func__, strerror(errno));
+            free(links.pads);
+            free(links.links);
+            return -errno;
+        }
+
+        for (i = 0; i < entity->info.pads; ++i) {
+            entity->pads[i].entity = entity;
+            entity->pads[i].index = links.pads[i].index;
+            entity->pads[i].flags = links.pads[i].flags;
+        }
+
+        for (i = 0; i < entity->info.links; ++i) {
+            struct media_link_desc *link = &links.links[i];
+            struct media_link *fwdlink;
+            struct media_link *backlink;
+            struct media_entity *source;
+            struct media_entity *sink;
+
+            source = media_get_entity_by_id(media, link->source.entity);
+            sink = media_get_entity_by_id(media, link->sink.entity);
+            if (source == NULL || sink == NULL) {
+                LOGE(
+                      "WARNING entity %u link %u from %u/%u to %u/%u is invalid!",
+                      id, i, link->source.entity,
+                      link->source.index,
+                      link->sink.entity,
+                      link->sink.index);
+                ret = -EINVAL;
+            } else {
+                fwdlink = media_entity_add_link(source);
+                fwdlink->source = &source->pads[link->source.index];
+                fwdlink->sink = &sink->pads[link->sink.index];
+                fwdlink->flags = link->flags;
+
+                backlink = media_entity_add_link(sink);
+                backlink->source = &source->pads[link->source.index];
+                backlink->sink = &sink->pads[link->sink.index];
+                backlink->flags = link->flags;
+
+                fwdlink->twin = backlink;
+                backlink->twin = fwdlink;
+            }
+        }
+
+        free(links.pads);
+        free(links.links);
+    }
+    return ret;
+}
+
+#ifdef HAVE_LIBUDEV
+
+#include <libudev.h>
+
+static inline int media_udev_open(struct udev **udev)
+{
+    *udev = udev_new();
+    if (*udev == NULL)
+        return -ENOMEM;
+    return 0;
+}
+
+static inline void media_udev_close(struct udev *udev)
+{
+    if (udev != NULL)
+        udev_unref(udev);
+}
+
+static int media_get_devname_udev(struct udev *udev,
+        struct media_entity *entity)
+{
+    struct udev_device *device;
+    dev_t devnum;
+    const char *p;
+    int ret = -ENODEV;
+
+    if (udev == NULL)
+        return -EINVAL;
+
+    devnum = makedev(entity->info.v4l.major, entity->info.v4l.minor);
+    LOGE("looking up device: %u:%u",
+          major(devnum), minor(devnum));
+    device = udev_device_new_from_devnum(udev, 'c', devnum);
+    if (device) {
+        p = udev_device_get_devnode(device);
+        if (p) {
+            strncpy(entity->devname, p, sizeof(entity->devname));
+            entity->devname[sizeof(entity->devname) - 1] = '\0';
+        }
+        ret = 0;
+    }
+
+    udev_device_unref(device);
+
+    return ret;
+}
+
+#else    /* HAVE_LIBUDEV */
+
+struct udev;
+
+static inline int media_udev_open(struct udev **udev) { return 0; }
+
+static inline void media_udev_close(struct udev *udev) { }
+
+static inline int media_get_devname_udev(struct udev *udev,
+        struct media_entity *entity)
+{
+    return -ENOTSUP;
+}
+
+#endif    /* HAVE_LIBUDEV */
+
+static int media_get_devname_sysfs(struct media_entity *entity)
+{
+    //struct stat devstat;
+    char devname[32];
+    char sysname[32];
+    char target[1024];
+    char *p;
+    int ret;
+
+    sprintf(sysname, "/sys/dev/char/%u:%u", entity->info.v4l.major,
+        entity->info.v4l.minor);
+
+    ret = readlink(sysname, target, sizeof(target));
+    if (ret < 0)
+        return -errno;
+
+    target[ret] = '\0';
+    p = strrchr(target, '/');
+    if (p == NULL)
+        return -EINVAL;
+
+    sprintf(devname, "/tmp/%s", p + 1);
+
+    ret = mknod(devname, 0666 | S_IFCHR, MKDEV(81, entity->info.v4l.minor));
+    strcpy(entity->devname, devname);
+
+    return 0;
+}
+
+int get_media_fd(struct media_device *media)
+{
+    ssize_t num;
+    int media_node;
+    char *ptr;
+    char media_buf[6];
+
+    LOGV("%s(%s)", __func__, MEDIA_DEV);
+
+    media->fd = open(MEDIA_DEV, O_RDWR, 0);
+    if( media->fd < 0) {
+        LOGE("Open sysfs media device failed, media->fd : 0x%p", media->fd);
+        return -1;
+    }
+    LOGV("media->fd : %p", media->fd);
+
+    return media->fd;
+
+}
+
+static int media_enum_entities(struct media_device *media)
+{
+    struct media_entity *entity;
+    unsigned int size;
+    __u32 id;
+    int ret;
+    entity = (struct media_entity*)calloc(1,  sizeof(struct media_entity));
+    for (id = 0, ret = 0; ; id = entity->info.id) {
+        size = (media->entities_count + 1) * sizeof(*media->entities);
+        media->entities = (struct media_entity*)realloc(media->entities, size);
+
+        entity = &media->entities[media->entities_count];
+        memset(entity, 0, sizeof(*entity));
+        entity->fd = -1;
+        entity->info.id = id | MEDIA_ENT_ID_FLAG_NEXT;
+        entity->media = media;
+
+        ret = ioctl(media->fd, MEDIA_IOC_ENUM_ENTITIES, &entity->info);
+
+        if (ret < 0) {
+            ret = errno != EINVAL ? -errno : 0;
+            break;
+        }
+
+        /* Number of links (for outbound links) plus number of pads (for
+         * inbound links) is a good safe initial estimate of the total
+         * number of links.
+         */
+        entity->max_links = entity->info.pads + entity->info.links;
+
+        entity->pads = (struct media_pad*)malloc(entity->info.pads * sizeof(*entity->pads));
+        entity->links = (struct media_link*)malloc(entity->max_links * sizeof(*entity->links));
+        if (entity->pads == NULL || entity->links == NULL) {
+            ret = -ENOMEM;
+            break;
+        }
+
+        media->entities_count++;
+
+        /* Find the corresponding device name. */
+        if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE &&
+            media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+            continue;
+
+        /* Fall back to get the device name via sysfs */
+        media_get_devname_sysfs(entity);
+        if (ret < 0)
+            LOGE("media_get_devname failed");
+    }
+
+    return ret;
+}
+
+static void media_debug_default(void *ptr, ...)
+{
+    va_list argptr;
+    va_start(argptr, ptr);
+    vprintf((const char*)ptr, argptr);
+    va_end(argptr);
+}
+
+void media_debug_set_handler(struct media_device *media,
+                 void (*debug_handler)(void *, ...),
+                 void *debug_priv)
+{
+    if (debug_handler) {
+        media->debug_handler = debug_handler;
+        media->debug_priv = debug_priv;
+    } else {
+        media->debug_handler = media_debug_default;
+        media->debug_priv = NULL;
+    }
+}
+
+struct media_device *media_open_debug(
+    const char *name, void (*debug_handler)(void *, ...),
+    void *debug_priv)
+{
+    struct media_device *media;
+    int ret;
+
+    media = (struct media_device*)calloc(1, sizeof(struct media_device));
+    if (media == NULL) {
+        LOGE("%s: media : %p", __func__, media);
+        return NULL;
+    }
+
+    media_debug_set_handler(media, debug_handler, debug_priv);
+
+    LOGV("Opening media device %s", name);
+    LOGV("%s: media : %p", __func__, media);
+
+    media->fd = get_media_fd(media);
+    if (media->fd < 0) {
+        media_close(media);
+        LOGE("%s: failed get_media_fd %s",
+              __func__, name);
+        return NULL;
+    }
+
+    LOGV("%s: media->fd : %p", __func__, media->fd);
+    ret = media_enum_entities(media);
+
+    if (ret < 0) {
+        LOGE(
+              "%s: Unable to enumerate entities for device %s (%s)",
+              __func__, name, strerror(-ret));
+        media_close(media);
+        return NULL;
+    }
+
+    LOGV("Found %u entities", media->entities_count);
+    LOGV("Enumerating pads and links");
+
+    ret = media_enum_links(media);
+    if (ret < 0) {
+        LOGE(
+              "%s: Unable to enumerate pads and linksfor device %s",
+              __func__, name);
+        media_close(media);
+        return NULL;
+    }
+
+    return media;
+}
+
+struct media_device *media_open(void)
+{
+    return media_open_debug(NULL, (void (*)(void *, ...))fprintf, stdout);
+}
+
+void media_close(struct media_device *media)
+{
+    unsigned int i;
+
+    if (media->fd != -1)
+        close(media->fd);
+
+    for (i = 0; i < media->entities_count; ++i) {
+        struct media_entity *entity = &media->entities[i];
+
+        free(entity->pads);
+        free(entity->links);
+        if (entity->fd != -1)
+            close(entity->fd);
+    }
+
+    free(media->entities);
+    free(media);
+}
+
+struct media_pad *media_parse_pad(struct media_device *media,
+                  const char *p, char **endp)
+{
+    unsigned int entity_id, pad;
+    struct media_entity *entity;
+    char *end;
+
+    for (; isspace(*p); ++p);
+
+    if (*p == '"') {
+        for (end = (char *)p + 1; *end && *end != '"'; ++end);
+        if (*end != '"')
+            return NULL;
+
+        entity = media_get_entity_by_name(media, p + 1, end - p - 1);
+        if (entity == NULL)
+            return NULL;
+
+        ++end;
+    } else {
+        entity_id = strtoul(p, &end, 10);
+        entity = media_get_entity_by_id(media, entity_id);
+        if (entity == NULL)
+            return NULL;
+    }
+    for (; isspace(*end); ++end);
+
+    if (*end != ':')
+        return NULL;
+    for (p = end + 1; isspace(*p); ++p);
+
+    pad = strtoul(p, &end, 10);
+    for (p = end; isspace(*p); ++p);
+
+    if (pad >= entity->info.pads)
+        return NULL;
+
+    for (p = end; isspace(*p); ++p);
+    if (endp)
+        *endp = (char *)p;
+
+    return &entity->pads[pad];
+}
+
+struct media_link *media_parse_link(struct media_device *media,
+                    const char *p, char **endp)
+{
+    struct media_link *link;
+    struct media_pad *source;
+    struct media_pad *sink;
+    unsigned int i;
+    char *end;
+
+    source = media_parse_pad(media, p, &end);
+    if (source == NULL)
+        return NULL;
+
+    if (end[0] != '-' || end[1] != '>')
+        return NULL;
+    p = end + 2;
+
+    sink = media_parse_pad(media, p, &end);
+    if (sink == NULL)
+        return NULL;
+
+    *endp = end;
+
+    for (i = 0; i < source->entity->num_links; i++) {
+        link = &source->entity->links[i];
+
+        if (link->source == source && link->sink == sink)
+            return link;
+    }
+
+    return NULL;
+}
+
+int media_parse_setup_link(struct media_device *media,
+               const char *p, char **endp)
+{
+    struct media_link *link;
+    __u32 flags;
+    char *end;
+
+    link = media_parse_link(media, p, &end);
+    if (link == NULL) {
+        LOGE(
+              "%s: Unable to parse link", __func__);
+        return -EINVAL;
+    }
+
+    p = end;
+    if (*p++ != '[') {
+        LOGE("Unable to parse link flags");
+        return -EINVAL;
+    }
+
+    flags = strtoul(p, &end, 10);
+    for (p = end; isspace(*p); p++);
+    if (*p++ != ']') {
+        LOGE("Unable to parse link flags");
+        return -EINVAL;
+    }
+
+    for (; isspace(*p); p++);
+    *endp = (char *)p;
+
+    LOGV(
+          "Setting up link %u:%u -> %u:%u [%u]",
+          link->source->entity->info.id, link->source->index,
+          link->sink->entity->info.id, link->sink->index,
+          flags);
+
+    return media_setup_link(media, link->source, link->sink, flags);
+}
+
+int media_parse_setup_links(struct media_device *media, const char *p)
+{
+    char *end;
+    int ret;
+
+    do {
+        ret = media_parse_setup_link(media, p, &end);
+        if (ret < 0)
+            return ret;
+
+        p = end + 1;
+    } while (*end == ',');
+
+    return *end ? -EINVAL : 0;
+}
diff --git a/exynos5/hal/libcamera/mediactl.h b/exynos5/hal/libcamera/mediactl.h
new file mode 100644
index 0000000..f28ce16
--- /dev/null
+++ b/exynos5/hal/libcamera/mediactl.h
@@ -0,0 +1,270 @@
+/*
+ * Media controller interface library
+ *
+ * Copyright (C) 2010-2011 Ideas on board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MEDIA_H__
+#define __MEDIA_H__
+
+#include <media.h>
+
+#define GAIA_FW_BETA 1
+
+#ifndef GAIA_FW_BETA
+#define MEDIA_DEV                          "/dev/media1"    //M5MO : External ISP
+#else
+#define MEDIA_DEV                          "/dev/media2"    //4E5  : Internal ISP
+#endif
+
+#define MEDIA_MINOR                         0
+
+#define KF_MSG                              0x1
+#define KF_ANY                              0x2
+
+struct media_link {
+    struct media_pad *source;
+    struct media_pad *sink;
+    struct media_link *twin;
+    __u32 flags;
+    __u32 padding[3];
+};
+
+struct media_pad {
+    struct media_entity *entity;
+    __u32 index;
+    __u32 flags;
+    __u32 padding[3];
+};
+
+struct media_entity {
+    struct media_device *media;
+    struct media_entity_desc info;
+    struct media_pad *pads;
+    struct media_link *links;
+    unsigned int max_links;
+    unsigned int num_links;
+
+    char devname[32];
+    int fd;
+    __u32 padding[6];
+};
+
+struct media_device {
+    int fd;
+    struct media_entity *entities;
+    unsigned int entities_count;
+    void (*debug_handler)(void *, ...);
+    void *debug_priv;
+    __u32 padding[6];
+};
+
+#define media_dbg(media, ...) \
+    (media)->debug_handler((media)->debug_priv, __VA_ARGS__)
+
+/**
+ * @brief Set a handler for debug messages.
+ * @param media - device instance.
+ * @param debug_handler - debug message handler
+ * @param debug_priv - first argument to debug message handler
+ *
+ * Set a handler for debug messages that will be called whenever
+ * debugging information is to be printed. The handler expects an
+ * fprintf-like function.
+ */
+void media_debug_set_handler(
+    struct media_device *media, void (*debug_handler)(void *, ...),
+    void *debug_priv);
+
+/**
+ * @brief Open a media device with debugging enabled.
+ * @param name - name (including path) of the device node.
+ * @param debug_handler - debug message handler
+ * @param debug_priv - first argument to debug message handler
+ *
+ * Open the media device referenced by @a name and enumerate entities, pads and
+ * links.
+ *
+ * Calling media_open_debug() instead of media_open() is equivalent to
+ * media_open() and media_debug_set_handler() except that debugging is
+ * also enabled during media_open().
+ *
+ * @return A pointer to a newly allocated media_device structure instance on
+ * success and NULL on failure. The returned pointer must be freed with
+ * media_close when the device isn't needed anymore.
+ */
+struct media_device *media_open_debug(
+    const char *name, void (*debug_handler)(void *, ...),
+    void *debug_priv);
+
+/**
+ * @brief Open a media device.
+ * @param name - name (including path) of the device node.
+ *
+ * Open the media device referenced by @a name and enumerate entities, pads and
+ * links.
+ *
+ * @return A pointer to a newly allocated media_device structure instance on
+ * success and NULL on failure. The returned pointer must be freed with
+ * media_close when the device isn't needed anymore.
+ */
+struct media_device *media_open(void);
+
+/**
+ * @brief Close a media device.
+ * @param media - device instance.
+ *
+ * Close the @a media device instance and free allocated resources. Access to the
+ * device instance is forbidden after this function returns.
+ */
+void media_close(struct media_device *media);
+
+/**
+ * @brief Locate the pad at the other end of a link.
+ * @param pad - sink pad at one end of the link.
+ *
+ * Locate the source pad connected to @a pad through an enabled link. As only one
+ * link connected to a sink pad can be enabled at a time, the connected source
+ * pad is guaranteed to be unique.
+ *
+ * @return A pointer to the connected source pad, or NULL if all links connected
+ * to @a pad are disabled. Return NULL also if @a pad is not a sink pad.
+ */
+struct media_pad *media_entity_remote_source(struct media_pad *pad);
+
+/**
+ * @brief Get the type of an entity.
+ * @param entity - the entity.
+ *
+ * @return The type of @a entity.
+ */
+static inline unsigned int media_entity_type(struct media_entity *entity)
+{
+    return entity->info.type & MEDIA_ENT_TYPE_MASK;
+}
+
+/**
+ * @brief Find an entity by its name.
+ * @param media - media device.
+ * @param name - entity name.
+ * @param length - size of @a name.
+ *
+ * Search for an entity with a name equal to @a name.
+ *
+ * @return A pointer to the entity if found, or NULL otherwise.
+ */
+struct media_entity *media_get_entity_by_name(struct media_device *media,
+    const char *name, size_t length);
+
+/**
+ * @brief Find an entity by its ID.
+ * @param media - media device.
+ * @param id - entity ID.
+ *
+ * Search for an entity with an ID equal to @a id.
+ *
+ * @return A pointer to the entity if found, or NULL otherwise.
+ */
+struct media_entity *media_get_entity_by_id(struct media_device *media,
+    __u32 id);
+
+/**
+ * @brief Configure a link.
+ * @param media - media device.
+ * @param source - source pad at the link origin.
+ * @param sink - sink pad at the link target.
+ * @param flags - configuration flags.
+ *
+ * Locate the link between @a source and @a sink, and configure it by applying
+ * the new @a flags.
+ *
+ * Only the MEDIA_LINK_FLAG_ENABLED flag is writable.
+ *
+ * @return 0 on success, -1 on failure:
+ *       -ENOENT: link not found
+ *       - other error codes returned by MEDIA_IOC_SETUP_LINK
+ */
+int media_setup_link(struct media_device *media,
+    struct media_pad *source, struct media_pad *sink,
+    __u32 flags);
+
+/**
+ * @brief Reset all links to the disabled state.
+ * @param media - media device.
+ *
+ * Disable all links in the media device. This function is usually used after
+ * opening a media device to reset all links to a known state.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int media_reset_links(struct media_device *media);
+
+/**
+ * @brief Parse string to a pad on the media device.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to string where parsing ended
+ *
+ * Parse NULL terminated string describing a pad and return its struct
+ * media_pad instance.
+ *
+ * @return Pointer to struct media_pad on success, NULL on failure.
+ */
+struct media_pad *media_parse_pad(struct media_device *media,
+                  const char *p, char **endp);
+
+/**
+ * @brief Parse string to a link on the media device.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to p where parsing ended
+ *
+ * Parse NULL terminated string p describing a link and return its struct
+ * media_link instance.
+ *
+ * @return Pointer to struct media_link on success, NULL on failure.
+ */
+struct media_link *media_parse_link(struct media_device *media,
+                    const char *p, char **endp);
+
+/**
+ * @brief Parse string to a link on the media device and set it up.
+ * @param media - media device.
+ * @param p - input string
+ *
+ * Parse NULL terminated string p describing a link and its configuration
+ * and configure the link.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int media_parse_setup_link(struct media_device *media,
+               const char *p, char **endp);
+
+/**
+ * @brief Parse string to link(s) on the media device and set it up.
+ * @param media - media device.
+ * @param p - input string
+ *
+ * Parse NULL terminated string p describing link(s) separated by
+ * commas (,) and configure the link(s).
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int media_parse_setup_links(struct media_device *media, const char *p);
+
+#endif
diff --git a/exynos5/hal/libcamera/v4l2subdev.h b/exynos5/hal/libcamera/v4l2subdev.h
new file mode 100644
index 0000000..20e0557
--- /dev/null
+++ b/exynos5/hal/libcamera/v4l2subdev.h
@@ -0,0 +1,200 @@
+/*
+ * V4L2 subdev interface library
+ *
+ * Copyright (C) 2010-2011 Ideas on board SPRL
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SUBDEV_H__
+#define __SUBDEV_H__
+
+#include <v4l2-subdev.h>
+
+struct media_entity;
+
+/**
+ * @brief Open a sub-device.
+ * @param entity - sub-device media entity.
+ *
+ * Open the V4L2 subdev device node associated with @a entity. The file
+ * descriptor is stored in the media_entity structure.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_open(struct media_entity *entity);
+
+/**
+ * @brief Close a sub-device.
+ * @param entity - sub-device media entity.
+ *
+ * Close the V4L2 subdev device node associated with the @a entity and opened by
+ * a previous call to v4l2_subdev_open() (either explicit or implicit).
+ */
+void v4l2_subdev_close(struct media_entity *entity);
+
+/**
+ * @brief Retrieve the format on a pad.
+ * @param entity - subdev-device media entity.
+ * @param format - format to be filled.
+ * @param pad - pad number.
+ * @param which - identifier of the format to get.
+ *
+ * Retrieve the current format on the @a entity @a pad and store it in the
+ * @a format structure.
+ *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try format stored
+ * in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the current
+ * active format.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_get_format(struct media_entity *entity,
+    struct v4l2_mbus_framefmt *format, unsigned int pad,
+    enum v4l2_subdev_format_whence which);
+
+/**
+ * @brief Set the format on a pad.
+ * @param entity - subdev-device media entity.
+ * @param format - format.
+ * @param pad - pad number.
+ * @param which - identifier of the format to set.
+ *
+ * Set the format on the @a entity @a pad to @a format. The driver is allowed to
+ * modify the requested format, in which case @a format is updated with the
+ * modifications.
+ *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try format stored in the
+ * file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the device with an
+ * active format.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_set_format(struct media_entity *entity,
+    struct v4l2_mbus_framefmt *format, unsigned int pad,
+    enum v4l2_subdev_format_whence which);
+
+/**
+ * @brief Retrieve the crop rectangle on a pad.
+ * @param entity - subdev-device media entity.
+ * @param rect - crop rectangle to be filled.
+ * @param pad - pad number.
+ * @param which - identifier of the format to get.
+ *
+ * Retrieve the current crop rectangleon the @a entity @a pad and store it in
+ * the @a rect structure.
+ *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try crop rectangle
+ * stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the
+ * current active crop rectangle.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_get_crop(struct media_entity *entity, struct v4l2_rect *rect,
+    unsigned int pad, enum v4l2_subdev_format_whence which);
+
+/**
+ * @brief Set the crop rectangle on a pad.
+ * @param entity - subdev-device media entity.
+ * @param rect - crop rectangle.
+ * @param pad - pad number.
+ * @param which - identifier of the format to set.
+ *
+ * Set the crop rectangle on the @a entity @a pad to @a rect. The driver is
+ * allowed to modify the requested rectangle, in which case @a rect is updated
+ * with the modifications.
+ *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try crop rectangle
+ * stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the
+ * device with an active crop rectangle.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_set_crop(struct media_entity *entity, struct v4l2_rect *rect,
+    unsigned int pad, enum v4l2_subdev_format_whence which);
+
+/**
+ * @brief Retrieve the frame interval on a sub-device.
+ * @param entity - subdev-device media entity.
+ * @param interval - frame interval to be filled.
+ *
+ * Retrieve the current frame interval on subdev @a entity and store it in the
+ * @a interval structure.
+ *
+ * Frame interval retrieving is usually supported only on devices at the
+ * beginning of video pipelines, such as sensors.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+
+int v4l2_subdev_get_frame_interval(struct media_entity *entity,
+    struct v4l2_fract *interval);
+
+/**
+ * @brief Set the frame interval on a sub-device.
+ * @param entity - subdev-device media entity.
+ * @param interval - frame interval.
+ *
+ * Set the frame interval on subdev @a entity to @a interval. The driver is
+ * allowed to modify the requested frame interval, in which case @a interval is
+ * updated with the modifications.
+ *
+ * Frame interval setting is usually supported only on devices at the beginning
+ * of video pipelines, such as sensors.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_set_frame_interval(struct media_entity *entity,
+    struct v4l2_fract *interval);
+
+/**
+ * @brief Parse a string and apply format, crop and frame interval settings.
+ * @param media - media device.
+ * @param p - input string
+ * @param endp - pointer to string p where parsing ended (return)
+ *
+ * Parse string @a p and apply format, crop and frame interval settings to a
+ * subdev pad specified in @a p. @a endp will be written a pointer where
+ * parsing of @a p ended.
+ *
+ * Format strings are separeted by commas (,).
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p);
+
+/**
+ * @brief Convert media bus pixel code to string.
+ * @param code - input string
+ *
+ * Convert media bus pixel code @a code to a human-readable string.
+ *
+ * @return A pointer to a string on success, NULL on failure.
+ */
+const char *v4l2_subdev_pixelcode_to_string(enum v4l2_mbus_pixelcode code);
+
+/**
+ * @brief Parse string to media bus pixel code.
+ * @param string - input string
+ * @param lenght - length of the string
+ *
+ * Parse human readable string @a string to an media bus pixel code.
+ *
+ * @return media bus pixelcode on success, -1 on failure.
+ */
+enum v4l2_mbus_pixelcode v4l2_subdev_string_to_pixelcode(const char *string,
+                             unsigned int length);
+#endif