ADDED THE FIMC1 STUFF FOR NOTHING
authorPaul Kocialkowski <contact@paulk.fr>
Sat, 19 Jan 2013 21:26:04 +0000 (22:26 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Sat, 19 Jan 2013 21:26:04 +0000 (22:26 +0100)
(at least flip and rotation works well now)

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
exynos_camera.c
exynos_camera.h
exynos_v4l2.c

index 2b9ae40..58cb16f 100644 (file)
@@ -44,11 +44,17 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                .name = "M5MO",
                .facing = CAMERA_FACING_FRONT,
                .orientation = 90,
+               .rotation = 0,
+               .hflip = 1,
+               .vflip = 0,
        },
        {
                .name = "S5K5BAFX",
                .facing = CAMERA_FACING_BACK,
                .orientation = 90,
+               .rotation = 0,
+               .hflip = 0,
+               .vflip = 1,
        },
 };
 
@@ -237,16 +243,127 @@ int exynos_camera_preview(struct exynos_camera *exynos_camera)
        void *addr = NULL;
        int offset;
 
+       void *base;
+       int width, height, fmt;
+       void *base_out;
+       int width_out, height_out, fmt_out;
+
        int index;
        int rc;
 
        if (exynos_camera == NULL)
                return -EINVAL;
 
+       exynos_camera->preview_window->dequeue_buffer(exynos_camera->preview_window,
+               &buffer, &stride);
+       exynos_camera->gralloc->lock(exynos_camera->gralloc, *buffer, GRALLOC_USAGE_SW_WRITE_OFTEN,
+               0, 0, 640, 480, &addr);
+
        // FIMC1 V4L2
+#if 0
+       rc = exynos_v4l2_g_fmt_out(exynos_camera, 1, &width_out, &height_out, &fmt_out);
+       if (rc < 0) {
+               LOGE("%s: g fmt failed!", __func__);
+               return -1;
+       }
+
+       width = 640;
+       height = 480;
+       fmt = V4L2_PIX_FMT_NV12;
+
+       if (width_out != width || height_out != height || fmt_out != fmt) {
+               rc = exynos_v4l2_s_fmt_pix_out(exynos_camera, 1, width, height, fmt);
+               if (rc < 0) {
+                       LOGE("%s: s fmt failed!", __func__);
+                       return -1;
+               }
+       }
+
+       rc = exynos_v4l2_s_crop_out(exynos_camera, 1, 0, 0, width, height);
+       if (rc < 0) {
+               LOGE("%s: s crop failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_reqbufs_out(exynos_camera, 1, 1);
+       if (rc < 0) {
+               LOGE("%s: reqbufs failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_ROTATION, 90);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_HFLIP, 0);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
 
-       
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_VFLIP, 0);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
 
+       rc = exynos_v4l2_g_fbuf(exynos_camera, 1, &base, &width_out, &height_out, &fmt_out);
+       if (rc < 0) {
+               LOGE("%s: g fbuf failed!", __func__);
+               return -1;
+       }
+
+       base = addr;
+
+       if (base_out != base || width_out != width || height_out != height || fmt_out != fmt) {
+               rc = exynos_v4l2_s_fbuf(exynos_camera, 1, base, width, height, fmt);
+               if (rc < 0) {
+                       LOGE("%s: s fbuf failed!", __func__);
+                       return -1;
+               }
+       }
+
+       memset(&fimc_buf, 0, sizeof(fimc_buf));
+       fimc_buf.base[0] = base;
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 1, V4L2_CID_DST_INFO, (int) &fimc_buf);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_s_fmt_win(exynos_camera, 1, 0, 0, width, height);
+       if (rc < 0) {
+               LOGE("%s: s fmt failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_streamon_out(exynos_camera, 1);
+       if (rc < 0) {
+               LOGE("%s: streamon failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_qbuf_out(exynos_camera, 1, 0);
+       if (rc < 0) {
+               LOGE("%s: qbuf failed!", __func__);
+               return -1;
+       }
+
+       index = exynos_v4l2_dqbuf_out(exynos_camera, 1);
+       if (index < 0) {
+               LOGE("%s: dqbuf failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_streamoff_out(exynos_camera, 1);
+       if (rc < 0) {
+               LOGE("%s: streamon failed!", __func__);
+               return -1;
+       }
+#endif
        // FIMC0 V4L2
 
        rc = exynos_v4l2_poll(exynos_camera, 0);
@@ -273,11 +390,6 @@ int exynos_camera_preview(struct exynos_camera *exynos_camera)
 
        // Preview window
 
-       exynos_camera->preview_window->dequeue_buffer(exynos_camera->preview_window,
-               &buffer, &stride);
-       exynos_camera->gralloc->lock(exynos_camera->gralloc, *buffer, GRALLOC_USAGE_SW_WRITE_OFTEN,
-               0, 0, 640, 480, &addr);
-
        if (addr == NULL) {
                LOGE("Unable to get addr");
                return -1;
@@ -285,9 +397,6 @@ int exynos_camera_preview(struct exynos_camera *exynos_camera)
        offset = index*640*480*1.5;
 
        void *frame = (void *) ((int) exynos_camera->preview_memory->data + offset);
-
-int width= 640;
-int height=480;
 /*
             // the code below assumes YUV, not RGB
             {
@@ -351,8 +460,11 @@ void *exynos_camera_preview_thread(void *data)
                pthread_mutex_lock(&exynos_camera->preview_mutex);
 
                rc = exynos_camera_preview(exynos_camera);
-               if (rc < 0)
+               if (rc < 0) {
                        LOGE("%s: preview failed!", __func__);
+                       // TODO FIXME WTF REMOVE THAT ASAP
+                       exynos_camera->preview_enabled = 0;
+               }
 
                pthread_mutex_unlock(&exynos_camera->preview_mutex);
        }
@@ -483,6 +595,7 @@ int exynos_camera_start_preview(struct camera_device *dev)
 
        pthread_attr_t thread_attr;
 
+       int id;
        int rc;
        int i;
 
@@ -493,6 +606,10 @@ int exynos_camera_start_preview(struct camera_device *dev)
 
        exynos_camera = (struct exynos_camera *) dev->priv;
 
+       if (exynos_camera->config == NULL || exynos_camera->config->presets == NULL ||
+               exynos_camera->camera_id >= exynos_camera->config->presets_count)
+               return -EINVAL;
+
        // V4L2
 
        fmt = V4L2_PIX_FMT_NV21;
@@ -506,7 +623,7 @@ int exynos_camera_start_preview(struct camera_device *dev)
        width = 640;
        height = 480;
 
-       rc = exynos_v4l2_s_fmt_cap(exynos_camera, 0, width, height, fmt);
+       rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, fmt);
        if (rc < 0) {
                LOGE("%s: s fmt failed!", __func__);
                return -1;
@@ -578,6 +695,29 @@ int exynos_camera_start_preview(struct camera_device *dev)
                }
        }
 
+       id = exynos_camera->camera_id;
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_ROTATION,
+               exynos_camera->config->presets[i].rotation);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_HFLIP,
+               exynos_camera->config->presets[id].hflip);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
+
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_VFLIP,
+               exynos_camera->config->presets[id].vflip);
+       if (rc < 0) {
+               LOGE("%s: s ctrl failed!", __func__);
+               return -1;
+       }
+
        rc = exynos_v4l2_streamon_cap(exynos_camera, 0);
        if (rc < 0) {
                LOGE("%s: streamon failed!", __func__);
@@ -585,7 +725,7 @@ int exynos_camera_start_preview(struct camera_device *dev)
        }
 
        // Init FIMC1
-       rc = exynos_v4l2_open(exynos_camera, 2);
+       rc = exynos_v4l2_open(exynos_camera, 1);
        if (rc < 0) {
                LOGE("Unable to open v4l2 device");
                return -1;
@@ -885,6 +1025,8 @@ int exynos_camera_open(const struct hw_module_t* module, const char *camera_id,
        if (id >= exynos_camera->config->presets_count)
                goto error_preset;
 
+       exynos_camera->camera_id = id;
+
        rc = exynos_camera_init(exynos_camera, id);
        if (rc < 0) {
                LOGE("%s: Unable to init camera", __func__);
index c795302..21e3fa3 100644 (file)
@@ -63,6 +63,10 @@ struct exynos_camera_preset {
        int orientation;
        char *preview_sizes;
        char *picture_sizes;
+
+       int rotation;
+       int hflip;
+       int vflip;
 };
 
 struct exynos_v4l2_node {
@@ -94,6 +98,8 @@ struct exynos_camera {
 
        struct exynos_camera_callbacks callbacks;
 
+       int camera_id;
+
        gralloc_module_t *gralloc;
 
        pthread_t preview_thread;
@@ -155,23 +161,23 @@ int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id);
 
 // VIDIOC
 int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int index);
+       int type, int memory, int index);
 int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index);
 int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index);
 int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type);
+       int type, int memory);
 int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id);
 int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id);
 int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int count);
+       int type, int memory, int count);
 int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int count);
 int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int count);
 int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int index);
+       int type, int memory, int index);
 int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index);
 int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
@@ -194,12 +200,14 @@ int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_i
        int *width, int *height, int *fmt);
 int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int *width, int *height, int *fmt);
-int exynos_v4l2_s_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int type, int width, int height, int fmt);
-int exynos_v4l2_s_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int width, int height, int fmt);
-int exynos_v4l2_s_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int width, int height, int fmt);
+int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height);
 int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int type, int fmt);
 int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
@@ -220,5 +228,15 @@ int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_
        struct v4l2_streamparm *streamparm);
 int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        struct v4l2_streamparm *streamparm);
+int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int type, int left, int top, int width, int height);
+int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height);
+int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height);
+int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       void **base, int *width, int *height, int *fmt);
+int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       void *base, int width, int height, int fmt);
 
 #endif
index e69835c..4733e43 100644 (file)
@@ -177,7 +177,7 @@ int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
  */
 
 int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int index)
+       int type, int memory, int index)
 {
        struct v4l2_buffer buffer;
        int rc;
@@ -186,7 +186,7 @@ int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
                return -EINVAL;
 
        buffer.type = type;
-       buffer.memory = V4L2_MEMORY_MMAP;
+       buffer.memory = memory;
        buffer.index = index;
 
        rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QBUF, &buffer);
@@ -201,17 +201,19 @@ int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
 int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index)
 {
-       return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, index);
+       return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+               V4L2_MEMORY_MMAP, index);
 }
 
 int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index)
 {
-       return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, index);
+       return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+               V4L2_MEMORY_USERPTR, index);
 }
 
 int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type)
+       int type, int memory)
 {
        struct v4l2_buffer buffer;
        int rc;
@@ -221,7 +223,7 @@ int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
 
        memset(&buffer, 0, sizeof(buffer));
        buffer.type = type;
-       buffer.memory = V4L2_MEMORY_MMAP;
+       buffer.memory = memory;
 
        rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_DQBUF, &buffer);
        if (rc < 0) {
@@ -234,16 +236,18 @@ int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
 
 int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
 {
-       return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+       return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+               V4L2_MEMORY_MMAP);
 }
 
 int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
 {
-       return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+       return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+               V4L2_MEMORY_USERPTR);
 }
 
 int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int count)
+       int type, int memory, int count)
 {
        struct v4l2_requestbuffers requestbuffers;
        int rc;
@@ -251,9 +255,9 @@ int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        if (exynos_camera == NULL || count < 0)
                return -EINVAL;
 
-       requestbuffers.count = count;
        requestbuffers.type = type;
-       requestbuffers.memory = V4L2_MEMORY_MMAP;
+       requestbuffers.count = count;
+       requestbuffers.memory = memory;
 
        rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_REQBUFS, &requestbuffers);
        if (rc < 0) {
@@ -268,18 +272,18 @@ int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, int exynos_v4l2
        int count)
 {
        return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
-               count);
+               V4L2_MEMORY_MMAP, count);
 }
 
 int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int count)
 {
        return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
-               count);
+               V4L2_MEMORY_USERPTR, count);
 }
 
 int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
-       int type, int index)
+       int type, int memory, int index)
 {
        struct v4l2_buffer buffer;
        int rc;
@@ -289,7 +293,7 @@ int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id
 
        memset(&buffer, 0, sizeof(buffer));
        buffer.type = type;
-       buffer.memory = V4L2_MEMORY_MMAP;
+       buffer.memory = memory;
        buffer.index = index;
 
        rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYBUF, &buffer);
@@ -305,14 +309,14 @@ int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l
        int index)
 {
        return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
-               index);
+               V4L2_MEMORY_MMAP, index);
 }
 
 int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int index)
 {
        return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
-               index);
+               V4L2_MEMORY_USERPTR, index);
 }
 
 int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
@@ -448,7 +452,7 @@ int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_i
                width, height, fmt);
 }
 
-int exynos_v4l2_s_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int type, int width, int height, int fmt)
 {
        struct v4l2_format format;
@@ -473,20 +477,46 @@ int exynos_v4l2_s_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        return 0;
 }
 
-int exynos_v4l2_s_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int width, int height, int fmt)
 {
-       return exynos_v4l2_s_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+       return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
                width, height, fmt);
 }
 
-int exynos_v4l2_s_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int width, int height, int fmt)
 {
-       return exynos_v4l2_s_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+       return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
                width, height, fmt);
 }
 
+int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height)
+{
+       struct v4l2_format format;
+       int rc;
+
+       if (exynos_camera == NULL)
+               return -EINVAL;
+
+       memset(&format, 0, sizeof(format));
+       format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+       format.fmt.win.w.left = left;
+       format.fmt.win.w.top = top;
+       format.fmt.win.w.width = width;
+       format.fmt.win.w.height = height;
+
+
+       rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format);
+       if (rc < 0) {
+               LOGE("%s: ioctl failed", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
 int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
        int type, int fmt)
 {
@@ -648,3 +678,92 @@ int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, int exynos_v4l2_
        return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
                streamparm);
 }
+
+int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int type, int left, int top, int width, int height)
+{
+       struct v4l2_crop crop;
+       int rc;
+
+       if (exynos_camera == NULL)
+               return -EINVAL;
+
+       crop.type = type;
+       crop.c.left = left;
+       crop.c.top = top;
+       crop.c.width = width;
+       crop.c.height = height;
+
+       rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CROP, &crop);
+       if (rc < 0) {
+               LOGE("%s: ioctl failed", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height)
+{
+       return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+               left, top, width, height);
+}
+
+int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       int left, int top, int width, int height)
+{
+       return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+               left, top, width, height);
+}
+
+int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       void **base, int *width, int *height, int *fmt)
+{
+       struct v4l2_framebuffer framebuffer;
+       int rc;
+
+       if (exynos_camera == NULL)
+               return -EINVAL;
+
+       rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FBUF, &framebuffer);
+       if (rc < 0) {
+               LOGE("%s: ioctl failed", __func__);
+               return -1;
+       }
+
+       if (base != NULL)
+               *base = framebuffer.base;
+       if (width != NULL)
+               *width = framebuffer.fmt.width;
+       if (height != NULL)
+               *height = framebuffer.fmt.height;
+       if (fmt != NULL)
+               *fmt = framebuffer.fmt.pixelformat;
+
+       return 0;
+}
+
+int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
+       void *base, int width, int height, int fmt)
+{
+       struct v4l2_framebuffer framebuffer;
+       int rc;
+
+       if (exynos_camera == NULL)
+               return -EINVAL;
+
+       memset(&framebuffer, 0, sizeof(framebuffer));
+       framebuffer.base = base;
+       framebuffer.fmt.width = width;
+       framebuffer.fmt.height = height;
+       framebuffer.fmt.pixelformat = fmt;
+
+       rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FBUF, &framebuffer);
+       if (rc < 0) {
+               LOGE("%s: ioctl failed", __func__);
+               return -1;
+       }
+
+       return 0;
+}