diff options
author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-10-30 16:47:04 +0000 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-10-30 18:17:03 +0000 |
commit | 51420db3f615a78736153165a4439d1f099e15b7 (patch) | |
tree | aae2dff6ec2c09b49d4bbfa8d1024fb7a4766dc0 /camera | |
parent | 78012f3513540230a4617d95b81114218593f921 (diff) | |
download | device_samsung_smdk4412-common-51420db3f615a78736153165a4439d1f099e15b7.zip device_samsung_smdk4412-common-51420db3f615a78736153165a4439d1f099e15b7.tar.gz device_samsung_smdk4412-common-51420db3f615a78736153165a4439d1f099e15b7.tar.bz2 |
camera: Fix various focus-related errors
* Validate that the focus region is within legal boundaries
* Reset the region to sane values if bad ones are given
* Set a default empty region
* If auto focus exists, it must be the default
Fixes android.hardware.cts.CameraTest#testFocusAreas and
android.hardware.cts.CameraTest#testParameters
Change-Id: I3aafcccc2c6081ba44edb3283a850c55178fa90a
Diffstat (limited to 'camera')
-rw-r--r-- | camera/exynos_camera.c | 43 | ||||
-rw-r--r-- | camera/exynos_camera.h | 1 |
2 files changed, 37 insertions, 7 deletions
diff --git a/camera/exynos_camera.c b/camera/exynos_camera.c index f6817a3..b19ac6d 100644 --- a/camera/exynos_camera.c +++ b/camera/exynos_camera.c @@ -101,10 +101,10 @@ struct exynos_camera_preset exynos_camera_presets_smdk4x12[] = { .recording_size_values = "1280x720,1920x1080,720x480,640x480,352x288,320x240,176x144", .recording_format = "yuv420sp", - .focus_mode = "continuous-picture", + .focus_mode = "auto", .focus_mode_values = "auto,infinity,macro,fixed,continuous-picture,continuous-video", .focus_distances = "0.15,1.20,Infinity", - .focus_areas = NULL, + .focus_areas = "(0,0,0,0,0)", .max_num_focus_areas = 1, .zoom_supported = 1, @@ -466,6 +466,8 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id) 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); + sprintf(exynos_camera->raw_focus_areas,"%s", + 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); } @@ -588,6 +590,28 @@ int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id) return 0; } +static int validate_focus_areas(int l, int t, int r, int b, int w) { + if (!(l || r || t || b || w)) { + // All zeros is a valid area + return 0; + } + + // If existing, a focus area must be contained between -1000 and 1000, + // on both dimensions + if (l < -1000 || t < -1000 || r > 1000 || b > 1000) { + return -EINVAL; + } + // No superimposed or reverted edges + if (l >= r || t >= b) { + return -EINVAL; + } + // If there's an area defined, weight must be positive and up to 1000 + if ((l !=0 || r !=0) && (w < 1 || w > 1000)) { + return -EINVAL; + } + return 0; +} + int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force) { char *recording_hint_string; @@ -622,7 +646,7 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force) char *focus_mode_string; int focus_mode = 0; char *focus_areas_string; - int focus_left, focus_top, focus_right, focus_bottom, focus_weigth; + int focus_left, focus_top, focus_right, focus_bottom, focus_weight; int focus_x; int focus_y; @@ -852,13 +876,18 @@ int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force) 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; + focus_left = focus_top = focus_right = focus_bottom = focus_weight = 0; rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)", - &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weigth); + &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weight); if (rc != 5) { ALOGE("%s: Unable to scan focus areas", __func__); - } else if (focus_left != 0 && focus_top != 0 && focus_right != 0 && focus_bottom != 0) { + } else if (validate_focus_areas(focus_left, focus_top, focus_right, focus_bottom, focus_weight) != 0 || strstr(focus_areas_string, "),(")) { + exynos_param_string_set(exynos_camera, "focus-areas", + exynos_camera->raw_focus_areas); + return -EINVAL; + } else if ((focus_left != 0 || focus_right != 0) && (focus_top != 0 || focus_bottom != 0)) { + sprintf(exynos_camera->raw_focus_areas,"%s",focus_areas_string); focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000; focus_y = (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000; @@ -3750,7 +3779,7 @@ int exynos_camera_auto_focus_thread_start(struct exynos_camera *exynos_camera) if (exynos_camera->auto_focus_thread_enabled) { ALOGE("Auto-focus thread was already started!"); - return -1; + return 0; } pthread_mutex_init(&exynos_camera->auto_focus_mutex, NULL); diff --git a/camera/exynos_camera.h b/camera/exynos_camera.h index 8c0977a..9e3d4f8 100644 --- a/camera/exynos_camera.h +++ b/camera/exynos_camera.h @@ -429,6 +429,7 @@ struct exynos_camera { int iso; int metering; int image_stabilization; + char raw_focus_areas[PAGE_SIZE]; }; struct exynos_camera_addrs { |