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/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