Added flash, focus, panorama mode thus enabled
authorPaul Kocialkowski <contact@paulk.fr>
Sat, 2 Feb 2013 21:41:53 +0000 (22:41 +0100)
committerPaul Kocialkowski <contact@paulk.fr>
Sat, 2 Feb 2013 21:41:53 +0000 (22:41 +0100)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
exynos_camera.c
exynos_camera.h

index e24255a..0204611 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "exynos_camera.h"
 
+// TODO FIXME TODO; Add credit to samsung 
+
 /*
  * Devices configurations
  */
@@ -51,7 +53,9 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                .hflip = 0,
                .vflip = 0,
                .picture_format = V4L2_PIX_FMT_JPEG,
-               .focal_length = 400,
+               .focal_length = 4.03f,
+               .horizontal_view_angle = 60.5f,
+               .vertical_view_angle = 47.1f,
                .params = {
                        .preview_size_values = "1280x720,640x480,720x480,800x480,800x450,352x288,320x240,176x144",
                        .preview_size = "640x480",
@@ -76,11 +80,20 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                        .recording_size_values = "1920x1080,1280x720,720x480,640x480",
                        .recording_format = "yuv420sp",
 
+                       .focus_mode = "auto",
+                       .focus_mode_values = "auto,infinity,macro,fixed,facedetect,continuous-video",
+                       .focus_distances = "0.15,1.20,Infinity",
+                       .focus_areas = "(0,0,0,0,0)",
+                       .max_num_focus_areas = 1,
+
                        .zoom_supported = 1,
                        .smooth_zoom_supported = 0,
                        .zoom_ratios = "100,102,104,109,111,113,119,121,124,131,134,138,146,150,155,159,165,170,182,189,200,213,222,232,243,255,283,300,319,364,400",
                        .zoom = 0,
                        .max_zoom = 30,
+
+                       .flash_mode = "off",
+                       .flash_mode_values = "off,auto,on,torch",
                },
        },
        {
@@ -91,7 +104,9 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                .hflip = 0,
                .vflip = 0,
                .picture_format = V4L2_PIX_FMT_YUYV,
-               .focal_length = 278,
+               .focal_length = 2.73f,
+               .horizontal_view_angle = 51.2f,
+               .vertical_view_angle = 39.4f,
                .params = {
                        .preview_size_values = "640x480,352x288,320x240,176x144",
                        .preview_size = "640x480",
@@ -116,7 +131,14 @@ struct exynos_camera_preset exynos_camera_presets_galaxys2[] = {
                        .recording_size_values = "640x480",
                        .recording_format = "yuv420sp",
 
+                       .focus_mode = "fixed",
+                       .focus_mode_values = "fixed",
+                       .focus_distances = "0.20,0.25,Infinity",
+                       .focus_areas = NULL,
+                       .max_num_focus_areas = 0,
+
                        .zoom_supported = 0,
+                       .flash_mode = NULL,
                },
        },
 };
@@ -260,7 +282,7 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
        exynos_camera->camera_hflip = exynos_camera->config->presets[id].hflip;
        exynos_camera->camera_vflip = exynos_camera->config->presets[id].vflip;
        exynos_camera->camera_picture_format = exynos_camera->config->presets[id].picture_format;
-       exynos_camera->camera_focal_length = exynos_camera->config->presets[id].focal_length;
+       exynos_camera->camera_focal_length = (int) (exynos_camera->config->presets[id].focal_length * 100);
 
        // Recording preview
        exynos_param_string_set(exynos_camera, "preferred-preview-size-for-video",
@@ -312,6 +334,20 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
        exynos_param_string_set(exynos_camera, "video-frame-format",
                exynos_camera->config->presets[id].params.recording_format);
 
+       // Focus
+       exynos_param_string_set(exynos_camera, "focus-mode",
+               exynos_camera->config->presets[id].params.focus_mode);
+       exynos_param_string_set(exynos_camera, "focus-mode-values",
+               exynos_camera->config->presets[id].params.focus_mode_values);
+       exynos_param_string_set(exynos_camera, "focus-distances",
+               exynos_camera->config->presets[id].params.focus_distances);
+       if (exynos_camera->config->presets[id].params.max_num_focus_areas > 0) {
+               exynos_param_string_set(exynos_camera, "focus-areas",
+                       exynos_camera->config->presets[id].params.focus_areas);
+               exynos_param_int_set(exynos_camera, "max-num-focus-areas",
+                       exynos_camera->config->presets[id].params.max_num_focus_areas);
+       }
+
        // Zoom
        if (exynos_camera->config->presets[id].params.zoom_supported == 1) {
                exynos_param_string_set(exynos_camera, "zoom-supported", "true");
@@ -329,9 +365,19 @@ 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");
+       // Flash
+       exynos_param_string_set(exynos_camera, "flash-mode",
+               exynos_camera->config->presets[id].params.flash_mode);
+       exynos_param_string_set(exynos_camera, "flash-mode-values",
+               exynos_camera->config->presets[id].params.flash_mode_values);
+
+       // Camera
+       exynos_param_float_set(exynos_camera, "focal-length",
+               exynos_camera->config->presets[id].focal_length);
+       exynos_param_float_set(exynos_camera, "horizontal-view-angle",
+               exynos_camera->config->presets[id].horizontal_view_angle);
+       exynos_param_float_set(exynos_camera, "vertical-view-angle",
+               exynos_camera->config->presets[id].vertical_view_angle);
 
        rc = exynos_camera_params_apply(exynos_camera);
        if (rc < 0) {
@@ -374,12 +420,24 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
        int camera_sensor_mode;
        int camera_sensor_output_size;
 
-       char *metering_string;
-       int metering;
+       char *focus_mode_string;
+       int focus_mode;
+       char *focus_areas_string;
+       int focus_left, focus_top, focus_right, focus_bottom, focus_weigth;
+       int focus_x;
+       int focus_y;
 
        char *zoom_supported_string;
        int zoom, max_zoom;
 
+       char *flash_mode_string;
+       int flash_mode;
+
+       char *metering_string;
+       int metering;
+
+       int force ;
+
        int w, h;
        char *k;
        int rc;
@@ -387,12 +445,13 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
        if (exynos_camera == NULL)
                return -EINVAL;
 
-       /*
-        * Params stored in exynos_camera that require an immediate ioctl should
-        * be reset after preview_stop since the driver will reset the values.
-        * However, the params should be reset by the Android framework to their
-        * original state when preview restarts.
-        */
+       if (!exynos_camera->preview_params_set) {
+               LOGE("%s: Setting preview params", __func__);
+               exynos_camera->preview_params_set = 1;
+               force = 1;
+       } else {
+               force = 0;
+       }
 
        // Preview
        preview_size_string = exynos_param_string_get(exynos_camera, "preview-size");
@@ -477,7 +536,7 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
                exynos_camera->jpeg_thumbnail_quality = jpeg_thumbnail_quality;
 
        jpeg_quality = exynos_param_int_get(exynos_camera, "jpeg-quality");
-       if (jpeg_quality <= 100 && jpeg_quality >= 0 && jpeg_quality != exynos_camera->jpeg_quality) {
+       if (jpeg_quality <= 100 && jpeg_quality >= 0 && (jpeg_quality != exynos_camera->jpeg_quality || force)) {
                exynos_camera->jpeg_quality = jpeg_quality;
                rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality);
                if (rc < 0)
@@ -564,12 +623,69 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
                        LOGE("%s: s ctrl failed!", __func__);
        }
 
+       // Focus
+       focus_mode_string = exynos_param_string_get(exynos_camera, "focus-mode");
+       if (focus_mode_string != NULL) {
+               if (strcmp(focus_mode_string, "auto") == 0)
+                       focus_mode = FOCUS_MODE_AUTO;
+               else if (strcmp(focus_mode_string, "infinity") == 0)
+                       focus_mode = FOCUS_MODE_INFINITY;
+               else if (strcmp(focus_mode_string, "macro") == 0)
+                       focus_mode = FOCUS_MODE_MACRO;
+               else if (strcmp(focus_mode_string, "fixed") == 0)
+                       focus_mode = FOCUS_MODE_FIXED;
+               else if (strcmp(focus_mode_string, "facedetect") == 0)
+                       focus_mode = FOCUS_MODE_FACEDETECT;
+               else if (strcmp(focus_mode_string, "continuous-video") == 0)
+                       focus_mode = FOCUS_MODE_CONTINOUS;
+               else if (strcmp(focus_mode_string, "continuous-picture") == 0)
+                       focus_mode = FOCUS_MODE_CONTINOUS;
+               else
+                       focus_mode = FOCUS_MODE_AUTO;
+
+               if (focus_mode != exynos_camera->focus_mode || force) {
+                       exynos_camera->focus_mode = focus_mode;
+                       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode);
+                       if (rc < 0)
+                               LOGE("%s: s ctrl failed!", __func__);
+               }
+       }
+
+       focus_areas_string = exynos_param_string_get(exynos_camera, "focus-areas");
+       if (focus_areas_string != NULL) {
+               focus_left = focus_top = focus_right = focus_bottom = focus_weigth = 0;
+
+               rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)",
+                       &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weigth);
+               if (rc != 5)
+                       LOGE("%s: sscanf failed!", __func__);
+
+               focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000;
+               focus_y =  (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000;
+
+               if (focus_x != exynos_camera->focus_x || force) {
+                       exynos_camera->focus_x = focus_x;
+
+                       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_X, focus_x);
+                       if (rc < 0)
+                               LOGE("%s: s ctrl failed!", __func__);
+               }
+
+               if (focus_y != exynos_camera->focus_y || force) {
+                       exynos_camera->focus_y = focus_y;
+
+                       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_Y, focus_y);
+                       if (rc < 0)
+                               LOGE("%s: s ctrl failed!", __func__);
+               }
+       }
+
        // 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 && zoom != exynos_camera->zoom) {
+               if (zoom <= max_zoom && zoom >= 0 && (zoom != exynos_camera->zoom || force)) {
                        exynos_camera->zoom = zoom;
                        rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ZOOM, zoom);
                        if (rc < 0)
@@ -578,6 +694,28 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
 
        }
 
+       // Flash
+       flash_mode_string = exynos_param_string_get(exynos_camera, "flash-mode");
+       if (flash_mode_string != NULL) {
+               if (strcmp(flash_mode_string, "off") == 0)
+                       flash_mode = FLASH_MODE_OFF;
+               else if (strcmp(flash_mode_string, "auto") == 0)
+                       flash_mode = FLASH_MODE_AUTO;
+               else if (strcmp(flash_mode_string, "on") == 0)
+                       flash_mode = FLASH_MODE_ON;
+               else if (strcmp(flash_mode_string, "torch") == 0)
+                       flash_mode = FLASH_MODE_TORCH;
+               else
+                       flash_mode = FLASH_MODE_AUTO;
+
+               if (flash_mode != exynos_camera->flash_mode || force) {
+                       exynos_camera->flash_mode = flash_mode;
+                       rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FLASH_MODE, flash_mode);
+                       if (rc < 0)
+                               LOGE("%s: s ctrl failed!", __func__);
+               }
+       }
+
        // Metering
        metering_string = exynos_param_string_get(exynos_camera, "metering");
        if (metering_string != NULL) {
@@ -592,7 +730,7 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera)
                        metering = METERING_MATRIX;
                }
 
-               if (metering != exynos_camera->metering) {
+               if (metering != exynos_camera->metering || force) {
                        exynos_camera->metering = metering;
                        rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_METERING, metering);
                        if (rc < 0)
@@ -600,28 +738,6 @@ 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;
-}
-*/
-
        LOGD("%s: Preview size: %dx%d, picture size: %dx%d, recording size: %dx%d",
                __func__, preview_width, preview_height, picture_width, picture_height,
                recording_width, recording_height);
@@ -1771,6 +1887,8 @@ void exynos_camera_preview_stop(struct exynos_camera *exynos_camera)
                LOGE("%s: streamoff failed!", __func__);
        }
 
+       exynos_camera->preview_params_set = 0;
+
        if (exynos_camera->preview_memory != NULL && exynos_camera->preview_memory->release != NULL) {
                exynos_camera->preview_memory->release(exynos_camera->preview_memory);
                exynos_camera->preview_memory = NULL;
@@ -2324,7 +2442,7 @@ char *exynos_camera_get_parameters(struct camera_device *dev)
                LOGE("%s: Couldn't find any param", __func__);
                return strdup("");
        }
-LOGD("[%s]", params);
+
        return params;
 }
 
index c99caab..e985880 100644 (file)
@@ -94,11 +94,20 @@ struct exynos_camera_params {
        char *recording_size_values;
        char *recording_format;
 
+       char *focus_mode;
+       char *focus_mode_values;
+       char *focus_distances;
+       char *focus_areas;
+       int max_num_focus_areas;
+
        int zoom_supported;
        int smooth_zoom_supported;
        char *zoom_ratios;
        int zoom;
        int max_zoom;
+
+       char *flash_mode;
+       char *flash_mode_values;
 };
 
 struct exynos_camera_preset {
@@ -111,7 +120,10 @@ struct exynos_camera_preset {
        int vflip;
 
        int picture_format;
-       int focal_length;
+
+       float focal_length;
+       float horizontal_view_angle;
+       float vertical_view_angle;
 
        struct exynos_camera_params params;
 };
@@ -174,6 +186,7 @@ struct exynos_camera {
        struct preview_stream_ops *preview_window;
        camera_memory_t *preview_memory;
        int preview_buffers_count;
+       int preview_params_set;
 
        // Recording
        pthread_mutex_t recording_mutex;
@@ -207,10 +220,12 @@ struct exynos_camera {
        int recording_width;
        int recording_height;
        int recording_format;
+       int focus_mode;
+       int focus_x;
+       int focus_y;
        int zoom;
+       int flash_mode;
        int metering;
-       int focus_object_x;
-       int focus_object_y;
 };
 
 struct exynos_camera_addrs {