sounds like we're stable
authorPaul Kocialkowski <contact@paulk.fr>
Sun, 27 Jan 2013 13:57:57 +0000 (14:57 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Sun, 27 Jan 2013 13:57:57 +0000 (14:57 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
exynos_camera.c
exynos_camera.h

index d9f0445..ea647b5 100644 (file)
@@ -62,6 +62,9 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                .rotation = 0,
                .hflip = 0,
                .vflip = 1,
+               .params = {
+                       .zoom_supported = 0,
+               },
        },
 };
 
@@ -208,10 +211,8 @@ void exynos_camera_deinit(struct exynos_camera *exynos_camera)
        if (exynos_camera == NULL || exynos_camera->config == NULL)
                return;
 
-       for (i=0 ; i < exynos_camera->config->v4l2_nodes_count ; i++) {
-               id = exynos_camera->config->v4l2_nodes[i].id;
-               exynos_v4l2_close(exynos_camera, id);
-       }
+       exynos_v4l2_close(exynos_camera, 0);
+       exynos_v4l2_close(exynos_camera, 2);
 }
 
 // Params
@@ -223,15 +224,8 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
        if (exynos_camera == NULL || id >= exynos_camera->config->presets_count)
                return -EINVAL;
 
-       exynos_param_string_set(exynos_camera, "picture-format", "jpeg");
-       exynos_param_string_set(exynos_camera, "picture-format-values", "jpeg");
-
-       exynos_param_string_set(exynos_camera, "picture-size", "2560x1920");
-       exynos_param_string_set(exynos_camera, "picture-size-values",
-               "2560x1920,2048x1536,1600x1200,1280x960,640x480");
-
-       exynos_param_string_set(exynos_camera, "preview-format", "rgb565");
-       exynos_param_string_set(exynos_camera, "preview-format-values", "rgb565");
+       exynos_param_string_set(exynos_camera, "preview-format", "yuv420sp");
+       exynos_param_string_set(exynos_camera, "preview-format-values", "yuv420sp");
        exynos_param_string_set(exynos_camera, "preview-fps-range", "15000,30000");
        exynos_param_string_set(exynos_camera, "preview-fps-range-values", "(15000,30000)");
        exynos_param_int_set(exynos_camera, "preview-frame-rate", 15);
@@ -240,8 +234,12 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
        exynos_param_string_set(exynos_camera, "preview-size-values",
                "720x480,640x480,352x288,176x144");
 
-       exynos_param_string_set(exynos_camera, "focus-mode", "auto");
-       exynos_param_string_set(exynos_camera, "focus-mode-values", "auto");
+       exynos_param_string_set(exynos_camera, "picture-format", "jpeg");
+       exynos_param_string_set(exynos_camera, "picture-format-values", "jpeg");
+
+       exynos_param_string_set(exynos_camera, "picture-size", "2560x1920");
+       exynos_param_string_set(exynos_camera, "picture-size-values",
+               "2560x1920,2048x1536,1600x1200,1280x960,640x480");
 
        // Zoom
        if (exynos_camera->config->presets[id].params.zoom_supported == 1) {
@@ -260,6 +258,10 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
                exynos_param_string_set(exynos_camera, "zoom-supported", "false");
        }
 
+       // Focus
+       exynos_param_string_set(exynos_camera, "focus-mode", "auto");
+       exynos_param_string_set(exynos_camera, "focus-mode-values", "auto");
+
        rc = exynos_camera_params_apply(exynos_camera);
        if (rc < 0) {
                LOGE("%s: Unable to apply params", __func__);
@@ -271,15 +273,63 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
 
 int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
 {
-       char *zoom_supported;
+       char *preview_format_string;
+       char *preview_size_string;
+       int preview_format;
+       int preview_width = 0;
+       int preview_height = 0;
+       float preview_bpp;
+
+       char *zoom_supported_string;
        int zoom, max_zoom;
+
        int rc;
 
        if (exynos_camera == NULL)
                return -EINVAL;
 
-       zoom_supported = exynos_param_string_get(exynos_camera, "zoom-supported");
-       if (zoom_supported != NULL && strcmp(zoom_supported, "true") == 0) {
+       // Preview
+       preview_format_string = exynos_param_string_get(exynos_camera, "preview-format");
+       if (preview_format_string != NULL) {
+               if (strcmp(preview_format_string, "yuv420sp") == 0) {
+                       preview_format = V4L2_PIX_FMT_NV21;
+                       preview_bpp = 1.5f;
+               } else if (strcmp(preview_format_string, "yuv420p") == 0) {
+                       preview_format = V4L2_PIX_FMT_YUV420;
+                       preview_bpp = 1.5f;
+               } else if (strcmp(preview_format_string, "rgb565") == 0) {
+                       preview_format = V4L2_PIX_FMT_RGB565;
+                       preview_bpp = 2.0f;
+               } else if (strcmp(preview_format_string, "rgb8888") == 0) {
+                       preview_format = V4L2_PIX_FMT_RGB32;
+                       preview_bpp = 4.0f;
+               } else {
+                       preview_format = V4L2_PIX_FMT_NV21;
+                       preview_bpp = 1.5f;
+               }
+
+               if (preview_format != exynos_camera->preview_format) {
+                       exynos_camera->preview_format = preview_format;
+                       exynos_camera->preview_bpp = preview_bpp;
+               }
+       }
+
+       preview_size_string = exynos_param_string_get(exynos_camera, "preview-size");
+       if (preview_size_string != NULL) {
+               sscanf(preview_size_string, "%dx%d", &preview_width, &preview_height);
+
+               if (preview_width != 0 && preview_height != 0 &&
+                       preview_width != exynos_camera->preview_width &&
+                       preview_height != exynos_camera->preview_height) {
+                       exynos_camera->preview_width = preview_width;
+                       exynos_camera->preview_height = preview_height;
+               }
+               
+       }
+
+       // Zoom
+       zoom_supported_string = exynos_param_string_get(exynos_camera, "zoom-supported");
+       if (zoom_supported_string != NULL && strcmp(zoom_supported_string, "true") == 0) {
                zoom = exynos_param_int_get(exynos_camera, "zoom");
                max_zoom = exynos_param_int_get(exynos_camera, "max-zoom");
                if (zoom <= max_zoom && zoom >= 0) {
@@ -290,6 +340,28 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
 
        }
 
+       // Focus
+       
+
+/*
+int SecCamera::setObjectPosition(int x, int y)
+{
+    LOGV("%s(setObjectPosition(x=%d, y=%d))", __func__, x, y);
+
+    if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, x) < 0) {
+        LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_X", __func__);
+        return -1;
+    }
+
+    if (fimc_v4l2_s_ctrl(m_cam_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;
+}
+*/
+
        return 0;
 }
 
@@ -299,13 +371,13 @@ int exynos_camera_preview(struct exynos_camera *exynos_camera)
 {
        buffer_handle_t *buffer;
        int stride;
-       void *addr = NULL;
-       int offset;
 
-       void *base;
-       int width, height, fmt;
-       void *base_out;
-       int width_out, height_out, fmt_out;
+       int width, height;
+       float bpp;
+
+       int frame_size, offset;
+       void *preview_data;
+       void *window_data;
 
        int index;
        int rc;
@@ -339,23 +411,29 @@ int exynos_camera_preview(struct exynos_camera *exynos_camera)
 
        // Preview window
 
+       width = exynos_camera->preview_width;
+       height = exynos_camera->preview_height;
+       bpp = exynos_camera->preview_bpp;
+
        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);
+               0, 0, width, height, &window_data);
 
-       if (addr == NULL) {
-               LOGE("Unable to get addr");
+       if (window_data == NULL) {
+               LOGE("%s: gralloc lock failed!", __func__);
                return -1;
        }
-       offset = index*640*480*1.5;
 
-       void *frame = (void *) ((int) exynos_camera->preview_memory->data + offset);
+       frame_size = (int) ((float) width * (float) height * bpp);
+       offset = index * frame_size;
 
-       memcpy(addr, frame, 640*480*1.5);
+       preview_data = (void *) ((int) exynos_camera->preview_memory->data + offset);
+       memcpy(window_data, preview_data, frame_size);
 
-       exynos_camera->gralloc->unlock(exynos_camera->gralloc, *buffer);
+       // TODO: callback
 
+       exynos_camera->gralloc->unlock(exynos_camera->gralloc, *buffer);
        exynos_camera->preview_window->enqueue_buffer(exynos_camera->preview_window,
                buffer);
 
@@ -402,8 +480,9 @@ void *exynos_camera_preview_thread(void *data)
 int exynos_camera_preview_start(struct exynos_camera *exynos_camera)
 {
        struct v4l2_streamparm streamparm;
-       unsigned int fmt;
-       int width, height, fps, frame_size;
+       int width, height, format;
+       float bpp;
+       int fps, frame_size;
        int fd;
 
        pthread_attr_t thread_attr;
@@ -423,18 +502,19 @@ int exynos_camera_preview_start(struct exynos_camera *exynos_camera)
 
        // V4L2
 
-       fmt = V4L2_PIX_FMT_NV21;
+       format = exynos_camera->preview_format;
 
-       rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, fmt);
+       rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, format);
        if (rc < 0) {
                LOGE("%s: enum fmt failed!", __func__);
                return -1;
        }
 
-       width = 640;
-       height = 480;
+       width = exynos_camera->preview_width;
+       height = exynos_camera->preview_height;
+       bpp = exynos_camera->preview_bpp;
 
-       rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, fmt, V4L2_PIX_FMT_MODE_PREVIEW);
+       rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_PREVIEW);
        if (rc < 0) {
                LOGE("%s: s fmt failed!", __func__);
                return -1;
@@ -446,7 +526,7 @@ int exynos_camera_preview_start(struct exynos_camera *exynos_camera)
                return -1;
        }
 
-       rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, 8);
+       rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, EXYNOS_CAMERA_MAX_BUFFERS_COUNT);
        if (rc < 0) {
                LOGE("%s: s ctrl failed!", __func__);
                return -1;
@@ -466,15 +546,17 @@ int exynos_camera_preview_start(struct exynos_camera *exynos_camera)
                return -1;
        }
 
+       frame_size = (int) ((float) width * (float) height * bpp);
        for (i=0 ; i < exynos_camera->preview_buffers_count ; i++) {
                rc = exynos_v4l2_querybuf_cap(exynos_camera, 0, i);
                if (rc < 0) {
                        LOGE("%s: querybuf failed!", __func__);
                        return -1;
                }
-       }
 
-       frame_size = 640 * 480 * 1.5;
+               if (rc != frame_size)
+                       LOGE("%s: Frame size mismatch: %d/%d", __func__, frame_size, rc);
+       }
 
        if (exynos_camera->callbacks.request_memory != NULL) {
                fd = exynos_v4l2_find_fd(exynos_camera, 0);
@@ -617,7 +699,7 @@ void *exynos_camera_auto_focus_thread(void *data)
        LOGE("%s: Starting thread", __func__);
        exynos_camera->auto_focus_thread_running = 1;
 
-       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, 1);
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON);
        if (rc < 0) {
                LOGE("%s: s ctrl failed!", __func__);
                auto_focus_result = 0;
@@ -655,6 +737,10 @@ void *exynos_camera_auto_focus_thread(void *data)
        }
 
 thread_exit:
+       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF);
+       if (rc < 0)
+               LOGE("%s: s ctrl failed!", __func__);
+
        if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify))
                exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS,
                        (int32_t) auto_focus_result, 0, exynos_camera->callbacks.user);
@@ -707,6 +793,11 @@ void exynos_camera_auto_focus_stop(struct exynos_camera *exynos_camera)
        if (exynos_camera == NULL)
                return;
 
+       if (!exynos_camera->auto_focus_enabled) {
+               LOGE("Auto-focus was already stopped!");
+               return;
+       }
+
        pthread_mutex_lock(&exynos_camera->auto_focus_mutex);
 
        // Disable auto-focus to make the thread end
@@ -856,45 +947,11 @@ int exynos_camera_picture(struct exynos_camera *exynos_camera)
                picture_main_memory->release(picture_main_memory);
        }
 
-/*
-E/exynos_camera( 2647): main (0x0, 0x254686) thumb(0x3a0000, 0xb1d7) post(0x3afc00)
-offset = 3afc00
-size = 46b400
-diff = 768000 = 640 * 480 * 2.5
-
-*/
-       // 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;
-       }
-       offset = index*640*480*1.5;
-
-       void *frame = (void *) ((int) exynos_camera->preview_memory->data + offset);
-
-       memcpy(addr, frame, 640*480*1.5);
-
-       exynos_camera->gralloc->unlock(exynos_camera->gralloc, *buffer);
-
-       exynos_camera->preview_window->enqueue_buffer(exynos_camera->preview_window,
-               buffer);
-*/
-/*
-       rc = exynos_camera_preview_start(exynos_camera);
-       if (rc < 0) {
-               LOGE("%s: Unable to start preview!", __func__);
-               return -1;
+       if (exynos_camera->picture_memory != NULL && exynos_camera->picture_memory->release != NULL) {
+               exynos_camera->picture_memory->release(exynos_camera->picture_memory);
+               exynos_camera->picture_memory = NULL;
        }
 
-       // Unlock preview lock (all should be set already)
-       pthread_mutex_unlock(&exynos_camera->preview_lock_mutex);
-*/
        return 0;
 }
 
@@ -936,7 +993,7 @@ int exynos_camera_picture_start(struct exynos_camera *exynos_camera)
 {
        pthread_attr_t thread_attr;
 
-       int width, height, fmt;
+       int width, height, format;
 
        int fd;
        int rc;
@@ -949,9 +1006,9 @@ int exynos_camera_picture_start(struct exynos_camera *exynos_camera)
 
        // V4L2
 
-       fmt = V4L2_PIX_FMT_JPEG;
+       format = V4L2_PIX_FMT_JPEG;
 
-       rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, fmt);
+       rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, format);
        if (rc < 0) {
                LOGE("%s: enum fmt failed!", __func__);
                return -1;
@@ -960,7 +1017,7 @@ int exynos_camera_picture_start(struct exynos_camera *exynos_camera)
        width = 3264;
        height = 2448;
 
-       rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, fmt, V4L2_PIX_FMT_MODE_CAPTURE);
+       rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_CAPTURE);
        if (rc < 0) {
                LOGE("%s: s fmt failed!", __func__);
                return -1;
@@ -1053,6 +1110,9 @@ int exynos_camera_set_preview_window(struct camera_device *dev,
        struct preview_stream_ops *w)
 {
        struct exynos_camera *exynos_camera;
+
+       int width, height, format, hal_format;
+
        buffer_handle_t *buffer;
        int stride;
        void *addr = NULL;
@@ -1078,7 +1138,7 @@ int exynos_camera_set_preview_window(struct camera_device *dev,
 
        if (exynos_camera->preview_buffers_count <= 0) {
                LOGE("%s: Invalid preview buffers count", __func__);
-               goto error;
+               exynos_camera->preview_buffers_count = EXYNOS_CAMERA_MAX_BUFFERS_COUNT;
        }
 
        rc = w->set_buffer_count(w, exynos_camera->preview_buffers_count);
@@ -1094,8 +1154,29 @@ int exynos_camera_set_preview_window(struct camera_device *dev,
                goto error;
        }
 
-       // TODO: Get this from params
-       rc = w->set_buffers_geometry(w, 640, 480, HAL_PIXEL_FORMAT_YCrCb_420_SP);
+       width = exynos_camera->preview_width;
+       height = exynos_camera->preview_height;
+       format = exynos_camera->preview_format;
+
+       switch (format) {
+               case V4L2_PIX_FMT_NV21:
+                       hal_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+                       break;
+               case V4L2_PIX_FMT_YUV420:
+                       hal_format = HAL_PIXEL_FORMAT_YV12;
+                       break;
+               case V4L2_PIX_FMT_RGB565:
+                       hal_format = HAL_PIXEL_FORMAT_RGB_565;
+                       break;
+               case V4L2_PIX_FMT_RGB32:
+                       hal_format = HAL_PIXEL_FORMAT_RGBX_8888;
+                       break;
+               default:
+                       hal_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+                       break;
+       }
+
+       rc = w->set_buffers_geometry(w, width, height, hal_format);
        if (rc) {
                LOGE("%s: Unable to set buffers geometry", __func__);
                goto error;
@@ -1302,6 +1383,8 @@ int exynos_camera_cancel_picture(struct camera_device *dev)
 {
        LOGD("%s(%p)", __func__, dev);
 
+       // TODO FIXME
+
        return 0;
 }
 
@@ -1372,7 +1455,16 @@ int exynos_camera_send_command(struct camera_device *dev,
 
 void exynos_camera_release(struct camera_device *dev)
 {
+       struct exynos_camera *exynos_camera;
+
        LOGD("%s(%p)", __func__, dev);
+
+       if (dev == NULL || dev->priv == NULL)
+               return;
+
+       exynos_camera = (struct exynos_camera *) dev->priv;
+
+       exynos_camera_deinit(exynos_camera);
 }
 
 int exynos_camera_dump(struct camera_device *dev, int fd)
@@ -1425,10 +1517,7 @@ int exynos_camera_close(hw_device_t *device)
        camera_device = (struct camera_device *) device;
 
        if (camera_device->priv != NULL) {
-               exynos_camera = (struct exynos_camera *) camera_device->priv;
-               exynos_camera_deinit(exynos_camera);
-
-               free(exynos_camera);
+               free(camera_device->priv);
        }
 
        free(camera_device);
index d1e5106..b2c02f5 100644 (file)
@@ -28,6 +28,7 @@
 
 #define EXYNOS_CAMERA_MAX_PRESETS_COUNT                2
 #define EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT     4
+#define EXYNOS_CAMERA_MAX_BUFFERS_COUNT                8
 
 #define EXYNOS_CAMERA_MSG_ENABLED(msg) \
        (exynos_camera->messages_enabled & msg)
@@ -146,6 +147,15 @@ struct exynos_camera {
        int picture_enabled;
        camera_memory_t *picture_memory;
        int picture_buffer_length;
+
+       // Params
+       int preview_width;
+       int preview_height;
+       int preview_format;
+       float preview_bpp;
+       int zoom;
+       int focus_object_x;
+       int focus_object_y;
 };
 
 // This is because the linux header uses anonymous union