blob: 6ef2dc67833d06bf81b2044468e2df63297270ab [file] [log] [blame]
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001/*
2 * Copyright (C) 2013 Paul Kocialkowski
3 *
4 * Based on crespo libcamera and exynos4 hal libcamera:
5 * Copyright 2008, The Android Open Source Project
6 * Copyright 2010, Samsung Electronics Co. LTD
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <time.h>
26#include <errno.h>
27#include <malloc.h>
28#include <sys/stat.h>
29#include <sys/types.h>
30#include <sys/time.h>
31#include <sys/mman.h>
32#include <sys/ioctl.h>
33
34#include <asm/types.h>
35
36#define LOG_TAG "exynos_camera"
37#include <utils/Log.h>
38#include <utils/Timers.h>
39
40#include "exynos_camera.h"
41
42#define BIG2LITTLE_ENDIAN(big) ((big & 0xff) << 24 | (big & 0xff00) << 8 | (big & 0xff0000) >> 8 | (big & 0xff000000) >> 24)
43
44/*
45 * Devices configurations
46 */
47
48struct exynos_camera_mbus_resolution exynos_camera_mbus_resolutions_s5k6a3_smdk4x12[] = {
49 // 16:9 ratio
50 { 1280, 720, 1344, 756 },
51 // 4:3 ratio
52 { 1280, 960, 1392, 1044 },
53 { 960, 720, 1392, 1044 },
54 { 640, 480, 1392, 1044 },
55 { 320, 240, 1392, 1044 },
56 // 1:1 ratio
57 { 1392, 1392, 1392, 1392 },
58 { 704, 704, 1392, 1392 },
59 { 320, 320, 1392, 1392 },
60};
61
62struct exynos_camera_preset exynos_camera_presets_smdk4x12[] = {
63 {
64 .name = "S5C73M3",
65 .facing = CAMERA_FACING_BACK,
66 .orientation = 90,
67 .rotation = 0,
68 .hflip = 0,
69 .vflip = 0,
70 .capture_format = V4L2_PIX_FMT_INTERLEAVED,
71 .picture_format = 0,
72 .fimc_is = 0,
73 .focal_length = 3.7f,
74 .horizontal_view_angle = 63.0f,
75 .vertical_view_angle = 49.3f,
76 .metering = METERING_CENTER,
77 .params = {
78 .preview_size_values = "960x720,1280x720,1184x666,960x640,704x576,640x480,352x288,320x240",
79 .preview_size = "960x720",
80 .preview_format_values = "yuv420sp,yuv420p,rgb565",
81 .preview_format = "yuv420sp",
82 .preview_frame_rate_values = "30,20,15",
83 .preview_frame_rate = 30,
84 .preview_fps_range_values = "(15000,15000),(15000,30000),(30000,30000)",
85 .preview_fps_range = "15000,30000",
86
87 .picture_size_values = "640x480,1024x768,1280x720,1600x1200,2560x1920,3264x2448,2048x1536,3264x1836,2048x1152,3264x2176",
88 .picture_size = "3264x2448",
89 .picture_format_values = "jpeg",
90 .picture_format = "jpeg",
91 .jpeg_thumbnail_size_values = "160x120,160x90,144x96",
92 .jpeg_thumbnail_width = 160,
Dheeraj CVRa50844d2013-12-14 10:54:53 -060093 .jpeg_thumbnail_height = 120,
Paul Kocialkowskib31c4462013-09-01 19:22:36 +020094 .jpeg_thumbnail_quality = 100,
95 .jpeg_quality = 90,
96
97 .video_snapshot_supported = 0,
98 .full_video_snap_supported = 0,
99
100 .recording_size = "1280x720",
101 .recording_size_values = "1280x720,1920x1080,720x480,640x480,352x288,320x240,176x144",
102 .recording_format = "yuv420sp",
103
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000104 .focus_mode = "auto",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200105 .focus_mode_values = "auto,infinity,macro,fixed,continuous-picture,continuous-video",
106 .focus_distances = "0.15,1.20,Infinity",
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000107 .focus_areas = "(0,0,0,0,0)",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200108 .max_num_focus_areas = 1,
109
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600110 .max_detected_faces = 15,
111
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200112 .zoom_supported = 1,
113 .smooth_zoom_supported = 0,
114 .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",
115 .zoom = 0,
116 .max_zoom = 30,
117
Javier Ferrer199a88b2013-10-08 17:47:29 +0200118 .auto_exposure_lock_supported = 1,
119 .auto_exposure_lock = 0,
120
121 .auto_white_balance_lock_supported = 1,
122 .auto_white_balance_lock = 0,
123
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200124 .flash_mode = "off",
125 .flash_mode_values = "off,auto,on,torch",
126
127 .exposure_compensation = 0,
128 .exposure_compensation_step = 0.5,
129 .min_exposure_compensation = -4,
130 .max_exposure_compensation = 4,
131
132 .whitebalance = "auto",
133 .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight",
134
Javier Ferrer15ca29a2013-09-09 13:53:49 +0200135 .antibanding = "auto",
136 .antibanding_values = "off,auto,50hz,60hz",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200137
138 .scene_mode = "auto",
mcampbellsmith2f654f92013-12-06 00:07:26 +1100139 .scene_mode_values = "auto,portrait,landscape,night,beach,snow,sunset,fireworks,action,party,candlelight,dusk-dawn,fall-color,text,back-light,high-sensitivity",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200140
141 .effect = "none",
142 .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green",
143
144 .iso = "auto",
145 .iso_values = "auto,ISO100,ISO200,ISO400,ISO800",
Javier Ferrer98d50c62013-09-17 23:49:39 +0200146
147 .image_stabilization = "off",
148 .image_stabilization_values = "on,off",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200149 },
150 .mbus_resolutions = NULL,
151 .mbus_resolutions_count = 0,
152 },
153 {
154 .name = "S5K6A3",
155 .facing = CAMERA_FACING_FRONT,
156 .orientation = 270,
157 .rotation = 0,
158 .hflip = 0,
159 .vflip = 0,
160 .capture_format = 0,
161 .picture_format = V4L2_PIX_FMT_YUYV,
162 .fimc_is = 1,
163 .focal_length = 2.73f,
164 .horizontal_view_angle = 52.58f,
165 .vertical_view_angle = 52.58f,
166 .metering = METERING_CENTER,
167 .params = {
168 .preview_size_values = "1280x720,960x720,640x480,320x240,704x704,320x320",
169 .preview_size = "960x720",
170 .preview_format_values = "yuv420sp,yuv420p,rgb565",
171 .preview_format = "yuv420sp",
172 .preview_frame_rate_values = "30,20,15,8",
173 .preview_frame_rate = 30,
174 .preview_fps_range_values = "(8000,8000),(15000,15000),(15000,30000),(30000,30000)",
175 .preview_fps_range = "15000,30000",
176
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600177 .picture_size_values = "1280x960,1392x1392,640x480,1280x720,720x480,320x240",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200178 .picture_size = "1280x960",
179 .picture_format_values = "jpeg",
180 .picture_format = "jpeg",
181 .jpeg_thumbnail_size_values = "160x120,160x160,160x90,144x96",
182 .jpeg_thumbnail_width = 160,
183 .jpeg_thumbnail_height = 120,
184 .jpeg_thumbnail_quality = 100,
185 .jpeg_quality = 90,
186
187 .video_snapshot_supported = 0,
188 .full_video_snap_supported = 0,
189
190 .recording_size = "1280x720",
191 .recording_size_values = "1280x720,720x480,640x480,352x288,320x320,320x240,176x144",
192 .recording_format = "yuv420sp",
193
194 .focus_mode = "fixed",
195 .focus_mode_values = "infinity,fixed",
196 .focus_distances = "0.20,0.25,Infinity",
197 .focus_areas = NULL,
198 .max_num_focus_areas = 0,
199
200 .zoom_supported = 0,
201
Javier Ferrer199a88b2013-10-08 17:47:29 +0200202 .auto_exposure_lock_supported = 0,
203 .auto_exposure_lock = 0,
204
205 .auto_white_balance_lock_supported = 0,
206 .auto_white_balance_lock = 0,
207
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200208 .flash_mode = NULL,
209 .flash_mode_values = NULL,
210
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600211 .max_detected_faces = 5,
212
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200213 .exposure_compensation = 0,
214 .exposure_compensation_step = 0.5,
215 .min_exposure_compensation = -4,
216 .max_exposure_compensation = 4,
217
218 .whitebalance = "auto",
219 .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight",
220
221 .antibanding = NULL,
222 .antibanding_values = NULL,
223
224 .scene_mode = NULL,
225 .scene_mode_values = NULL,
226
227 .effect = "none",
228 .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green",
229
230 .iso = "auto",
231 .iso_values = "auto",
Javier Ferrer98d50c62013-09-17 23:49:39 +0200232
233 .image_stabilization = "off",
234 .image_stabilization_values = "off",
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200235 },
236 .mbus_resolutions = (struct exynos_camera_mbus_resolution *) &exynos_camera_mbus_resolutions_s5k6a3_smdk4x12,
237 .mbus_resolutions_count = 8,
238 },
239};
240
241struct exynos_v4l2_node exynos_v4l2_nodes_smdk4x12[] = {
242 { // FIMC0 is used for capture
243 .id = 0,
244 .node = "/dev/video0",
245 },
246 { // FIMC1 is used for preview output
247 .id = 1,
248 .node = "/dev/video1",
249 },
250 { // FIMC2 is used for picture output
251 .id = 2,
252 .node = "/dev/video2",
253 },
254 { // FIMC3 is used for recording output
255 .id = 3,
256 .node = "/dev/video3",
257 },
258};
259
260struct exynox_camera_config exynos_camera_config_smdk4x12 = {
261 .presets = (struct exynos_camera_preset *) &exynos_camera_presets_smdk4x12,
262 .presets_count = 2,
263 .v4l2_nodes = (struct exynos_v4l2_node *) &exynos_v4l2_nodes_smdk4x12,
264 .v4l2_nodes_count = 4,
265};
266
267/*
268 * Exynos Camera
269 */
270
271struct exynox_camera_config *exynos_camera_config =
272 &exynos_camera_config_smdk4x12;
273
274int exynos_camera_start(struct exynos_camera *exynos_camera, int id)
275{
276 int rc;
277
278 if (exynos_camera == NULL || id >= exynos_camera->config->presets_count)
279 return -EINVAL;
280
281 // ION
282
283#ifdef EXYNOS_ION
284 rc = exynos_ion_init(exynos_camera);
285 if (rc < 0) {
286 ALOGE("%s: Unable to init ION", __func__);
287 goto error;
288 }
289
290 rc = exynos_ion_open(exynos_camera);
291 if (rc < 0) {
292 ALOGE("%s: Unable to open ION", __func__);
293 goto error;
294 }
295#endif
296
297 // V4L2
298
299 rc = exynos_v4l2_init(exynos_camera);
300 if (rc < 0) {
301 ALOGE("%s: Unable to init v4l2", __func__);
302 goto error;
303 }
304
305 // FIMC0
306
307 rc = exynos_v4l2_open(exynos_camera, 0);
308 if (rc < 0) {
309 ALOGE("%s: Unable to open v4l2 device", __func__);
310 goto error;
311 }
312
313 rc = exynos_v4l2_querycap_cap(exynos_camera, 0);
314 if (rc < 0) {
315 ALOGE("%s: Unable to query capabilities", __func__);
316 goto error;
317 }
318
319 rc = exynos_v4l2_enum_input(exynos_camera, 0, id);
320 if (rc < 0) {
321 ALOGE("%s: Unable to enumerate input", __func__);
322 goto error;
323 }
324
325 rc = exynos_v4l2_s_input(exynos_camera, 0, id);
326 if (rc < 0) {
327 ALOGE("%s: Unable to set inputs", __func__);
328 goto error;
329 }
330
331 // Recording
332
333 exynos_camera->recording_metadata = 1;
334
335 // Params
336
337 rc = exynos_camera_params_init(exynos_camera, id);
338 if (rc < 0) {
339 ALOGE("%s: Unable to init params", __func__);
340 goto error;
341 }
342
343 // Gralloc
344
345 rc = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **) &exynos_camera->gralloc);
346 if (rc)
347 ALOGE("%s: Unable to get gralloc module", __func__);
348
349 rc = 0;
350 goto complete;
351
352error:
353 exynos_v4l2_close(exynos_camera, 0);
354
355#ifdef EXYNOS_ION
356 exynos_ion_close(exynos_camera);
357#endif
358
359 rc = -1;
360
361complete:
362 return rc;
363}
364
365void exynos_camera_stop(struct exynos_camera *exynos_camera)
366{
367 int i;
368 int id;
369
370 if (exynos_camera == NULL || exynos_camera->config == NULL)
371 return;
372
373 exynos_v4l2_close(exynos_camera, 0);
374
375#ifdef EXYNOS_ION
376 exynos_ion_close(exynos_camera);
377#endif
378}
379
380// Params
381
382int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id)
383{
384 int rc;
385
386 if (exynos_camera == NULL || id >= exynos_camera->config->presets_count)
387 return -EINVAL;
388
389 // Camera params
390
391 exynos_camera->camera_rotation = exynos_camera->config->presets[id].rotation;
392 exynos_camera->camera_hflip = exynos_camera->config->presets[id].hflip;
393 exynos_camera->camera_vflip = exynos_camera->config->presets[id].vflip;
394 exynos_camera->camera_capture_format = exynos_camera->config->presets[id].capture_format;
395 exynos_camera->camera_picture_format = exynos_camera->config->presets[id].picture_format;
396 exynos_camera->camera_fimc_is = exynos_camera->config->presets[id].fimc_is;
397 exynos_camera->camera_focal_length = (int) (exynos_camera->config->presets[id].focal_length * 100);
398 exynos_camera->camera_metering = exynos_camera->config->presets[id].metering;
399
400 exynos_camera->camera_mbus_resolutions = exynos_camera->config->presets[id].mbus_resolutions;
401 exynos_camera->camera_mbus_resolutions_count = exynos_camera->config->presets[id].mbus_resolutions_count;
402
403 // Recording preview
404
405 exynos_param_string_set(exynos_camera, "preferred-preview-size-for-video",
406 exynos_camera->config->presets[id].params.preview_size);
407
408 // Preview
409
410 exynos_param_string_set(exynos_camera, "preview-size-values",
411 exynos_camera->config->presets[id].params.preview_size_values);
412 exynos_param_string_set(exynos_camera, "preview-size",
413 exynos_camera->config->presets[id].params.preview_size);
414 exynos_param_string_set(exynos_camera, "preview-format-values",
415 exynos_camera->config->presets[id].params.preview_format_values);
416 exynos_param_string_set(exynos_camera, "preview-format",
417 exynos_camera->config->presets[id].params.preview_format);
418 exynos_param_string_set(exynos_camera, "preview-frame-rate-values",
419 exynos_camera->config->presets[id].params.preview_frame_rate_values);
420 exynos_param_int_set(exynos_camera, "preview-frame-rate",
421 exynos_camera->config->presets[id].params.preview_frame_rate);
422 exynos_param_string_set(exynos_camera, "preview-fps-range-values",
423 exynos_camera->config->presets[id].params.preview_fps_range_values);
424 exynos_param_string_set(exynos_camera, "preview-fps-range",
425 exynos_camera->config->presets[id].params.preview_fps_range);
426
427 // Picture
428
429 exynos_param_string_set(exynos_camera, "picture-size-values",
430 exynos_camera->config->presets[id].params.picture_size_values);
431 exynos_param_string_set(exynos_camera, "picture-size",
432 exynos_camera->config->presets[id].params.picture_size);
433 exynos_param_string_set(exynos_camera, "picture-format-values",
434 exynos_camera->config->presets[id].params.picture_format_values);
435 exynos_param_string_set(exynos_camera, "picture-format",
436 exynos_camera->config->presets[id].params.picture_format);
437 exynos_param_string_set(exynos_camera, "jpeg-thumbnail-size-values",
438 exynos_camera->config->presets[id].params.jpeg_thumbnail_size_values);
439 exynos_param_int_set(exynos_camera, "jpeg-thumbnail-width",
440 exynos_camera->config->presets[id].params.jpeg_thumbnail_width);
441 exynos_param_int_set(exynos_camera, "jpeg-thumbnail-height",
442 exynos_camera->config->presets[id].params.jpeg_thumbnail_height);
443 exynos_param_int_set(exynos_camera, "jpeg-thumbnail-quality",
444 exynos_camera->config->presets[id].params.jpeg_thumbnail_quality);
445 exynos_param_int_set(exynos_camera, "jpeg-quality",
446 exynos_camera->config->presets[id].params.jpeg_quality);
447
448 if (exynos_camera->config->presets[id].params.video_snapshot_supported == 1)
449 exynos_param_string_set(exynos_camera, "video-snapshot-supported", "true");
450 if (exynos_camera->config->presets[id].params.full_video_snap_supported == 1)
451 exynos_param_string_set(exynos_camera, "full-video-snap-supported", "true");
452
453 // Recording
454
455 exynos_param_string_set(exynos_camera, "video-size",
456 exynos_camera->config->presets[id].params.recording_size);
457 exynos_param_string_set(exynos_camera, "video-size-values",
458 exynos_camera->config->presets[id].params.recording_size_values);
459 exynos_param_string_set(exynos_camera, "video-frame-format",
460 exynos_camera->config->presets[id].params.recording_format);
461
462 // Focus
463
464 exynos_param_string_set(exynos_camera, "focus-mode",
465 exynos_camera->config->presets[id].params.focus_mode);
466 exynos_param_string_set(exynos_camera, "focus-mode-values",
467 exynos_camera->config->presets[id].params.focus_mode_values);
468 exynos_param_string_set(exynos_camera, "focus-distances",
469 exynos_camera->config->presets[id].params.focus_distances);
470 if (exynos_camera->config->presets[id].params.max_num_focus_areas > 0) {
471 exynos_param_string_set(exynos_camera, "focus-areas",
472 exynos_camera->config->presets[id].params.focus_areas);
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000473 sprintf(exynos_camera->raw_focus_areas,"%s",
474 exynos_camera->config->presets[id].params.focus_areas);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200475 exynos_param_int_set(exynos_camera, "max-num-focus-areas",
476 exynos_camera->config->presets[id].params.max_num_focus_areas);
477 }
478
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600479 // Face Detection
480 exynos_camera->max_detected_faces = exynos_camera->config->presets[id].params.max_detected_faces;
481 exynos_param_int_set(exynos_camera, "max-num-detected-faces-hw",
482 exynos_camera->max_detected_faces);
483
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200484 // Zoom
485
486 if (exynos_camera->config->presets[id].params.zoom_supported == 1) {
487 exynos_param_string_set(exynos_camera, "zoom-supported", "true");
488
489 if (exynos_camera->config->presets[id].params.smooth_zoom_supported == 1)
490 exynos_param_string_set(exynos_camera, "smooth-zoom-supported", "true");
491
492 if (exynos_camera->config->presets[id].params.zoom_ratios != NULL)
493 exynos_param_string_set(exynos_camera, "zoom-ratios", exynos_camera->config->presets[id].params.zoom_ratios);
494
495 exynos_param_int_set(exynos_camera, "zoom", exynos_camera->config->presets[id].params.zoom);
496 exynos_param_int_set(exynos_camera, "max-zoom", exynos_camera->config->presets[id].params.max_zoom);
497
498 } else {
499 exynos_param_string_set(exynos_camera, "zoom-supported", "false");
500 }
501
Javier Ferrer199a88b2013-10-08 17:47:29 +0200502 // AE lock
503
504 if (exynos_camera->config->presets[id].params.auto_exposure_lock_supported == 1) {
505 exynos_param_string_set(exynos_camera, "auto-exposure-lock-supported", "true");
506
507 if (exynos_camera->config->presets[id].params.auto_exposure_lock)
508 exynos_param_string_set(exynos_camera, "auto-exposure-lock", "true");
509 else
510 exynos_param_string_set(exynos_camera, "auto-exposure-lock", "false");
511 }
512
513 // AWB lock
514
515 if (exynos_camera->config->presets[id].params.auto_white_balance_lock_supported == 1) {
516 exynos_param_string_set(exynos_camera, "auto-whitebalance-lock-supported", "true");
517
518 if (exynos_camera->config->presets[id].params.auto_white_balance_lock)
519 exynos_param_string_set(exynos_camera, "auto-whitebalance-lock", "true");
520 else
521 exynos_param_string_set(exynos_camera, "auto-whitebalance-lock", "false");
522 }
523
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200524 // Flash
525
526 exynos_param_string_set(exynos_camera, "flash-mode",
527 exynos_camera->config->presets[id].params.flash_mode);
528 exynos_param_string_set(exynos_camera, "flash-mode-values",
529 exynos_camera->config->presets[id].params.flash_mode_values);
530
531 // Exposure
532
533 exynos_param_int_set(exynos_camera, "exposure-compensation",
534 exynos_camera->config->presets[id].params.exposure_compensation);
535 exynos_param_float_set(exynos_camera, "exposure-compensation-step",
536 exynos_camera->config->presets[id].params.exposure_compensation_step);
537 exynos_param_int_set(exynos_camera, "min-exposure-compensation",
538 exynos_camera->config->presets[id].params.min_exposure_compensation);
539 exynos_param_int_set(exynos_camera, "max-exposure-compensation",
540 exynos_camera->config->presets[id].params.max_exposure_compensation);
541
542 // Antibanding
543
544 exynos_param_string_set(exynos_camera, "antibanding",
545 exynos_camera->config->presets[id].params.antibanding);
546 exynos_param_string_set(exynos_camera, "antibanding-values",
547 exynos_camera->config->presets[id].params.antibanding_values);
548
549 // WB
550
551 exynos_param_string_set(exynos_camera, "whitebalance",
552 exynos_camera->config->presets[id].params.whitebalance);
553 exynos_param_string_set(exynos_camera, "whitebalance-values",
554 exynos_camera->config->presets[id].params.whitebalance_values);
555
556 // Scene mode
557
558 exynos_param_string_set(exynos_camera, "scene-mode",
559 exynos_camera->config->presets[id].params.scene_mode);
560 exynos_param_string_set(exynos_camera, "scene-mode-values",
561 exynos_camera->config->presets[id].params.scene_mode_values);
562
563 // Effect
564
565 exynos_param_string_set(exynos_camera, "effect",
566 exynos_camera->config->presets[id].params.effect);
567 exynos_param_string_set(exynos_camera, "effect-values",
568 exynos_camera->config->presets[id].params.effect_values);
569
570 // ISO
571
572 exynos_param_string_set(exynos_camera, "iso",
573 exynos_camera->config->presets[id].params.iso);
574 exynos_param_string_set(exynos_camera, "iso-values",
575 exynos_camera->config->presets[id].params.iso_values);
576
Javier Ferrer98d50c62013-09-17 23:49:39 +0200577 // Image stabilization (Anti-shake)
578
579 exynos_param_string_set(exynos_camera, "image-stabilization",
580 exynos_camera->config->presets[id].params.image_stabilization);
581 exynos_param_string_set(exynos_camera, "image-stabilization-values",
582 exynos_camera->config->presets[id].params.image_stabilization_values);
583
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200584 // Camera
585
586 exynos_param_float_set(exynos_camera, "focal-length",
587 exynos_camera->config->presets[id].focal_length);
588 exynos_param_float_set(exynos_camera, "horizontal-view-angle",
589 exynos_camera->config->presets[id].horizontal_view_angle);
590 exynos_param_float_set(exynos_camera, "vertical-view-angle",
591 exynos_camera->config->presets[id].vertical_view_angle);
592
593 rc = exynos_camera_params_apply(exynos_camera, 1);
594 if (rc < 0) {
595 ALOGE("%s: Unable to apply params", __func__);
596 return -1;
597 }
598
599 return 0;
600}
601
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000602static int validate_focus_areas(int l, int t, int r, int b, int w) {
603 if (!(l || r || t || b || w)) {
604 // All zeros is a valid area
605 return 0;
606 }
607
608 // If existing, a focus area must be contained between -1000 and 1000,
609 // on both dimensions
610 if (l < -1000 || t < -1000 || r > 1000 || b > 1000) {
611 return -EINVAL;
612 }
613 // No superimposed or reverted edges
614 if (l >= r || t >= b) {
615 return -EINVAL;
616 }
617 // If there's an area defined, weight must be positive and up to 1000
618 if ((l !=0 || r !=0) && (w < 1 || w > 1000)) {
619 return -EINVAL;
620 }
621 return 0;
622}
623
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200624int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force)
625{
626 char *recording_hint_string;
627 char *recording_preview_size_string;
628
629 char *preview_size_string;
630 int preview_width = 0;
631 int preview_height = 0;
632 char *preview_format_string;
633 int preview_format;
634 int preview_fps;
635
636 char *picture_size_string;
637 int picture_width = 0;
638 int picture_height = 0;
639 char *picture_format_string;
640 int picture_format;
641
642 int jpeg_thumbnail_width;
643 int jpeg_thumbnail_height;
644 int jpeg_thumbnail_quality;
645 int jpeg_quality;
646
647 char *video_size_string;
648 int recording_width = 0;
649 int recording_height = 0;
650 char *video_frame_format_string;
651 int recording_format;
652 int camera_sensor_mode;
653 int fimc_is_mode = 0;
654
655 char *focus_mode_string;
Dheeraj CVR58f00472014-01-31 23:07:16 +0530656 int focus_mode = FOCUS_MODE_DEFAULT;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200657 char *focus_areas_string;
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000658 int focus_left, focus_top, focus_right, focus_bottom, focus_weight;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200659 int focus_x;
660 int focus_y;
661
662 char *zoom_supported_string;
663 int zoom, max_zoom;
664
Javier Ferrer199a88b2013-10-08 17:47:29 +0200665 char *ae_lock_supported_string;
666 char *ae_lock_string;
667 int ae_lock = 0;
668
669 char *awb_lock_supported_string;
670 char *awb_lock_string;
671 int awb_lock = 0;
672 int aeawb = 0;
673
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200674 char *flash_mode_string;
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600675 int flash_mode = 0;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200676
677 int exposure_compensation;
678 int min_exposure_compensation;
679 int max_exposure_compensation;
680
681 char *antibanding_string;
682 int antibanding;
683
684 char *whitebalance_string;
685 int whitebalance;
686
687 char *scene_mode_string;
688 int scene_mode;
689
690 char *effect_string;
691 int effect;
692
693 char *iso_string;
694 int iso;
695
Javier Ferrer98d50c62013-09-17 23:49:39 +0200696 char *image_stabilization_string;
697 int image_stabilization;
698
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200699 int w, h;
700 char *k;
701 int rc;
702
703 if (exynos_camera == NULL)
704 return -EINVAL;
705
706 // Preview
707
708 preview_size_string = exynos_param_string_get(exynos_camera, "preview-size");
709 if (preview_size_string != NULL) {
710 sscanf(preview_size_string, "%dx%d", &preview_width, &preview_height);
711
Ricardo Cerqueira2d2391e2013-10-30 17:23:03 +0000712 if (preview_width < 0 && preview_height < 0) {
713 char reset_preview[128];
714 sprintf(reset_preview, "%dx%d", exynos_camera->preview_width, exynos_camera->preview_height);
715 exynos_param_string_set(exynos_camera, "preview-size",
716 reset_preview);
717 return -EINVAL;
718 }
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200719 if (preview_width != 0 && preview_width != exynos_camera->preview_width)
720 exynos_camera->preview_width = preview_width;
721 if (preview_height != 0 && preview_height != exynos_camera->preview_height)
722 exynos_camera->preview_height = preview_height;
723 }
724
725 preview_format_string = exynos_param_string_get(exynos_camera, "preview-format");
726 if (preview_format_string != NULL) {
727 if (strcmp(preview_format_string, "yuv420sp") == 0) {
728 preview_format = V4L2_PIX_FMT_NV21;
729 } else if (strcmp(preview_format_string, "yuv420p") == 0) {
730 preview_format = V4L2_PIX_FMT_YUV420;
731 } else if (strcmp(preview_format_string, "rgb565") == 0) {
732 preview_format = V4L2_PIX_FMT_RGB565;
733 } else if (strcmp(preview_format_string, "rgb8888") == 0) {
734 preview_format = V4L2_PIX_FMT_RGB32;
735 } else {
736 ALOGE("%s: Unsupported preview format: %s", __func__, preview_format_string);
737 preview_format = V4L2_PIX_FMT_NV21;
738 }
739
740 if (preview_format != exynos_camera->preview_format)
741 exynos_camera->preview_format = preview_format;
742 }
743
744 preview_fps = exynos_param_int_get(exynos_camera, "preview-frame-rate");
745 if (preview_fps > 0)
746 exynos_camera->preview_fps = preview_fps;
747 else
748 exynos_camera->preview_fps = 0;
749
750 // Picture
751
752 picture_size_string = exynos_param_string_get(exynos_camera, "picture-size");
753 if (picture_size_string != NULL) {
754 sscanf(picture_size_string, "%dx%d", &picture_width, &picture_height);
755
756 if (picture_width != 0 && picture_height != 0 && (picture_width != exynos_camera->picture_width || picture_height != exynos_camera->picture_height)) {
757 exynos_camera->picture_width = picture_width;
758 exynos_camera->picture_height = picture_height;
759
760 if (exynos_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED) {
761 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_JPEG_RESOLUTION, (picture_width & 0xffff) << 16 | (picture_height & 0xffff));
762 if (rc < 0)
763 ALOGE("%s: Unablet to set jpeg resolution", __func__);
764 }
765 }
766 }
767
768 picture_format_string = exynos_param_string_get(exynos_camera, "picture-format");
769 if (picture_format_string != NULL) {
770 if (strcmp(picture_format_string, "jpeg") == 0) {
771 picture_format = V4L2_PIX_FMT_JPEG;
772 } else {
773 ALOGE("%s: Unsupported picture format: %s", __func__, picture_format_string);
774 picture_format = V4L2_PIX_FMT_JPEG;
775 }
776
777 if (picture_format != exynos_camera->picture_format)
778 exynos_camera->picture_format = picture_format;
779 }
780
781 jpeg_thumbnail_width = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-width");
782 if (jpeg_thumbnail_width > 0)
783 exynos_camera->jpeg_thumbnail_width = jpeg_thumbnail_width;
784
785 jpeg_thumbnail_height = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-height");
786 if (jpeg_thumbnail_height > 0)
787 exynos_camera->jpeg_thumbnail_height = jpeg_thumbnail_height;
788
789 jpeg_thumbnail_quality = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-quality");
790 if (jpeg_thumbnail_quality > 0)
791 exynos_camera->jpeg_thumbnail_quality = jpeg_thumbnail_quality;
792
793 jpeg_quality = exynos_param_int_get(exynos_camera, "jpeg-quality");
794 if (jpeg_quality <= 100 && jpeg_quality >= 0 && (jpeg_quality != exynos_camera->jpeg_quality || force)) {
795 exynos_camera->jpeg_quality = jpeg_quality;
796 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality);
797 if (rc < 0)
798 ALOGE("%s: Unable to set jpeg quality", __func__);
799 }
800
801 // Recording
802
803 video_size_string = exynos_param_string_get(exynos_camera, "video-size");
804 if (video_size_string == NULL)
805 video_size_string = exynos_param_string_get(exynos_camera, "preview-size");
806
807 if (video_size_string != NULL) {
808 sscanf(video_size_string, "%dx%d", &recording_width, &recording_height);
809
810 if (recording_width != 0 && recording_width != exynos_camera->recording_width)
811 exynos_camera->recording_width = recording_width;
812 if (recording_height != 0 && recording_height != exynos_camera->recording_height)
813 exynos_camera->recording_height = recording_height;
814 }
815
816 video_frame_format_string = exynos_param_string_get(exynos_camera, "video-frame-format");
817 if (video_frame_format_string != NULL) {
818 if (strcmp(video_frame_format_string, "yuv420sp") == 0) {
819 recording_format = V4L2_PIX_FMT_NV12;
820 } else if (strcmp(video_frame_format_string, "yuv420p") == 0) {
821 recording_format = V4L2_PIX_FMT_YUV420;
822 } else if (strcmp(video_frame_format_string, "rgb565") == 0) {
823 recording_format = V4L2_PIX_FMT_RGB565;
824 } else if (strcmp(video_frame_format_string, "rgb8888") == 0) {
825 recording_format = V4L2_PIX_FMT_RGB32;
826 } else {
827 ALOGE("%s: Unsupported recording format: %s", __func__, video_frame_format_string);
828 recording_format = V4L2_PIX_FMT_NV12;
829 }
830
831 if (recording_format != exynos_camera->recording_format)
832 exynos_camera->recording_format = recording_format;
833 }
834
835 recording_hint_string = exynos_param_string_get(exynos_camera, "recording-hint");
836 if (recording_hint_string != NULL && strcmp(recording_hint_string, "true") == 0) {
837 camera_sensor_mode = SENSOR_MOVIE;
838
839 k = exynos_param_string_get(exynos_camera, "preview-size-values");
840 while (recording_width != 0 && recording_height != 0) {
841 if (k == NULL)
842 break;
843
844 sscanf(k, "%dx%d", &w, &h);
845
846 // Look for same aspect ratio
847 if ((recording_width * h) / recording_height == w) {
848 preview_width = w;
849 preview_height = h;
850 break;
851 }
852
853 k = strchr(k, ',');
854 if (k == NULL)
855 break;
856
857 k++;
858 }
859
860 if (preview_width != 0 && preview_width != exynos_camera->preview_width)
861 exynos_camera->preview_width = preview_width;
862 if (preview_height != 0 && preview_height != exynos_camera->preview_height)
863 exynos_camera->preview_height = preview_height;
864
865 if (exynos_camera->camera_fimc_is)
866 fimc_is_mode = IS_MODE_PREVIEW_VIDEO;
867 } else {
868 camera_sensor_mode = SENSOR_CAMERA;
869
870 if (exynos_camera->camera_fimc_is)
871 fimc_is_mode = IS_MODE_PREVIEW_STILL;
872 }
873
874 // Switching modes
875
876 if (camera_sensor_mode != exynos_camera->camera_sensor_mode) {
877 exynos_camera->camera_sensor_mode = camera_sensor_mode;
878 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SENSOR_MODE, camera_sensor_mode);
879 if (rc < 0)
880 ALOGE("%s: Unable to set sensor mode", __func__);
881 }
882
883 if (exynos_camera->camera_fimc_is && fimc_is_mode != exynos_camera->fimc_is_mode) {
884 exynos_camera->fimc_is_mode = fimc_is_mode;
885
886 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, exynos_camera->fimc_is_mode);
887 if (rc < 0)
888 ALOGE("%s: Unable to set FIMC-IS scenario", __func__);
889 }
890
891 // Focus
892
893 focus_areas_string = exynos_param_string_get(exynos_camera, "focus-areas");
894 if (focus_areas_string != NULL) {
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000895 focus_left = focus_top = focus_right = focus_bottom = focus_weight = 0;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200896
897 rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)",
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000898 &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weight);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200899 if (rc != 5) {
900 ALOGE("%s: Unable to scan focus areas", __func__);
Ricardo Cerqueira51420db2013-10-30 16:47:04 +0000901 } else if (validate_focus_areas(focus_left, focus_top, focus_right, focus_bottom, focus_weight) != 0 || strstr(focus_areas_string, "),(")) {
902 exynos_param_string_set(exynos_camera, "focus-areas",
903 exynos_camera->raw_focus_areas);
904 return -EINVAL;
905 } else if ((focus_left != 0 || focus_right != 0) && (focus_top != 0 || focus_bottom != 0)) {
906 sprintf(exynos_camera->raw_focus_areas,"%s",focus_areas_string);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200907 focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000;
908 focus_y = (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000;
909
910 if (focus_x != exynos_camera->focus_x || force) {
911 exynos_camera->focus_x = focus_x;
912
913 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_X, focus_x);
914 if (rc < 0)
915 ALOGE("%s: Unable to set object x position", __func__);
916 }
917
918 if (focus_y != exynos_camera->focus_y || force) {
919 exynos_camera->focus_y = focus_y;
920
921 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_Y, focus_y);
922 if (rc < 0)
923 ALOGE("%s: Unable to set object y position", __func__);
924 }
Dheeraj CVR58f00472014-01-31 23:07:16 +0530925
Javier Ferrer0378c1e2014-03-23 01:27:02 +0100926 /* After taking a picture, focus-areas is reseted by stock camera app to the center of the screen */
927 if (! ( (focus_x == (preview_width / 2)) && (focus_y == (preview_height / 2)) )) {
928 //ALOGV("%s focus_mode changed to %d due to focus-areas='%s'", __func__, focus_mode, focus_areas_string);
929 focus_mode = FOCUS_MODE_TOUCH;
930 }
931 }
Dheeraj CVR58f00472014-01-31 23:07:16 +0530932
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200933 }
934
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200935 // Zoom
936
937 zoom_supported_string = exynos_param_string_get(exynos_camera, "zoom-supported");
938 if (zoom_supported_string != NULL && strcmp(zoom_supported_string, "true") == 0) {
939 zoom = exynos_param_int_get(exynos_camera, "zoom");
940 max_zoom = exynos_param_int_get(exynos_camera, "max-zoom");
941 if (zoom <= max_zoom && zoom >= 0 && (zoom != exynos_camera->zoom || force)) {
942 exynos_camera->zoom = zoom;
943 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ZOOM, zoom);
944 if (rc < 0)
945 ALOGE("%s: Unable to set camera zoom", __func__);
Ricardo Cerqueira2d2391e2013-10-30 17:23:03 +0000946 } else if (zoom > max_zoom) {
947 exynos_param_int_set(exynos_camera, "zoom", max_zoom);
948 return -EINVAL;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +0200949 }
950
951 }
952
Javier Ferrer199a88b2013-10-08 17:47:29 +0200953 // AE lock
954
955 ae_lock_supported_string = exynos_param_string_get(exynos_camera, "auto-exposure-lock-supported");
956 ae_lock_string = exynos_param_string_get(exynos_camera, "auto-exposure-lock");
957 if (ae_lock_supported_string != NULL && ae_lock_string != NULL && strcmp(ae_lock_supported_string, "true") == 0 && strcmp(ae_lock_string, "true") == 0)
958 ae_lock = 1;
959 else
960 ae_lock = 0;
961
962 // AWB lock
963
964 awb_lock_supported_string = exynos_param_string_get(exynos_camera, "auto-whitebalance-lock-supported");
965 awb_lock_string = exynos_param_string_get(exynos_camera, "auto-whitebalance-lock");
966 if (awb_lock_supported_string != NULL && awb_lock_string != NULL && strcmp(awb_lock_supported_string, "true") == 0 && strcmp(awb_lock_string, "true") == 0)
967 awb_lock = 1;
968 else
969 awb_lock = 0;
970
Dheeraj CVRa50844d2013-12-14 10:54:53 -0600971 // Scene mode
972
973 scene_mode_string = exynos_param_string_get(exynos_camera, "scene-mode");
974 if (scene_mode_string != NULL) {
975 if (strcmp(scene_mode_string, "auto") == 0)
976 scene_mode = SCENE_MODE_NONE;
977 else if (strcmp(scene_mode_string, "portrait") == 0) {
978 scene_mode = SCENE_MODE_PORTRAIT;
979 flash_mode = FLASH_MODE_AUTO;
980 } else if (strcmp(scene_mode_string, "landscape") == 0)
981 scene_mode = SCENE_MODE_LANDSCAPE;
982 else if (strcmp(scene_mode_string, "night") == 0)
983 scene_mode = SCENE_MODE_NIGHTSHOT;
984 else if (strcmp(scene_mode_string, "beach") == 0)
985 scene_mode = SCENE_MODE_BEACH_SNOW;
986 else if (strcmp(scene_mode_string, "snow") == 0)
987 scene_mode = SCENE_MODE_BEACH_SNOW;
988 else if (strcmp(scene_mode_string, "sunset") == 0)
989 scene_mode = SCENE_MODE_SUNSET;
990 else if (strcmp(scene_mode_string, "fireworks") == 0)
991 scene_mode = SCENE_MODE_FIREWORKS;
992 else if (strcmp(scene_mode_string, "action") == 0)
993 scene_mode = SCENE_MODE_SPORTS;
994 else if (strcmp(scene_mode_string, "party") == 0) {
995 scene_mode = SCENE_MODE_PARTY_INDOOR;
996 flash_mode = FLASH_MODE_AUTO;
997 } else if (strcmp(scene_mode_string, "candlelight") == 0)
998 scene_mode = SCENE_MODE_CANDLE_LIGHT;
999 else if (strcmp(scene_mode_string, "dusk-dawn") == 0)
1000 scene_mode = SCENE_MODE_DUSK_DAWN;
1001 else if (strcmp(scene_mode_string, "fall-color") == 0)
1002 scene_mode = SCENE_MODE_FALL_COLOR;
1003 else if (strcmp(scene_mode_string, "back-light") == 0)
1004 scene_mode = SCENE_MODE_BACK_LIGHT;
1005 else if (strcmp(scene_mode_string, "text") == 0)
1006 scene_mode = SCENE_MODE_TEXT;
1007 else if (strcmp(scene_mode_string, "high-sensitivity") == 0)
1008 scene_mode = SCENE_MODE_LOW_LIGHT;
1009 else
1010 scene_mode = SCENE_MODE_NONE;
1011
1012 if (scene_mode != exynos_camera->scene_mode || force) {
1013 exynos_camera->scene_mode = scene_mode;
1014 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, scene_mode);
1015 if (rc < 0)
1016 ALOGE("%s: Unable to set scene mode", __func__);
1017 }
1018
Dheeraj CVR58f00472014-01-31 23:07:16 +05301019 if (scene_mode != SCENE_MODE_NONE && !flash_mode && focus_mode == FOCUS_MODE_DEFAULT) {
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001020 flash_mode = FLASH_MODE_OFF;
1021 focus_mode = FOCUS_MODE_AUTO;
1022 }
Javier Ferrer199a88b2013-10-08 17:47:29 +02001023 }
1024
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001025 // Flash
1026
1027 flash_mode_string = exynos_param_string_get(exynos_camera, "flash-mode");
1028 if (flash_mode_string != NULL) {
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001029 if (flash_mode == 0) {
1030 if (strcmp(flash_mode_string, "off") == 0)
1031 flash_mode = FLASH_MODE_OFF;
1032 else if (strcmp(flash_mode_string, "auto") == 0)
1033 flash_mode = FLASH_MODE_AUTO;
1034 else if (strcmp(flash_mode_string, "on") == 0)
1035 flash_mode = FLASH_MODE_ON;
1036 else if (strcmp(flash_mode_string, "torch") == 0)
1037 flash_mode = FLASH_MODE_TORCH;
1038 else {
1039 exynos_param_string_set(exynos_camera, "flash-mode",
1040 exynos_camera->raw_flash_mode);
1041 return -EINVAL;
1042 }
Ricardo Cerqueira2d2391e2013-10-30 17:23:03 +00001043 }
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001044
1045 if (flash_mode != exynos_camera->flash_mode || force) {
1046 exynos_camera->flash_mode = flash_mode;
Ricardo Cerqueira2d2391e2013-10-30 17:23:03 +00001047 sprintf(exynos_camera->raw_flash_mode, "%s", flash_mode_string);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001048 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FLASH_MODE, flash_mode);
1049 if (rc < 0)
1050 ALOGE("%s:Unable to set flash mode", __func__);
1051 }
1052 }
1053
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001054 // Lock Auto Exposure and White Balance only when Flash is OFF
1055 if ((ae_lock != exynos_camera->ae_lock || awb_lock != exynos_camera->awb_lock || force) &&
1056 exynos_camera->flash_mode == FLASH_MODE_OFF) {
1057 exynos_camera->ae_lock = ae_lock;
1058 exynos_camera->awb_lock = awb_lock;
1059 aeawb = (ae_lock ? 0x1 : 0x0) | (awb_lock ? 0x2 : 0x0);
1060 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, aeawb);
1061 if (rc < 0)
1062 ALOGE("%s: Unable to set AEAWB lock", __func__);
1063 }
1064
1065 focus_mode_string = exynos_param_string_get(exynos_camera, "focus-mode");
1066 if (focus_mode_string != NULL) {
Dheeraj CVR58f00472014-01-31 23:07:16 +05301067 if (focus_mode == FOCUS_MODE_DEFAULT) {
1068 if (strcmp(focus_mode_string, "auto") == 0)
1069 focus_mode = FOCUS_MODE_AUTO;
1070 else if (strcmp(focus_mode_string, "infinity") == 0)
1071 focus_mode = FOCUS_MODE_INFINITY;
1072 else if (strcmp(focus_mode_string, "macro") == 0)
1073 focus_mode = FOCUS_MODE_MACRO;
1074 else if (strcmp(focus_mode_string, "fixed") == 0)
1075 focus_mode = FOCUS_MODE_FIXED;
1076 else if (strcmp(focus_mode_string, "facedetect") == 0)
1077 focus_mode = FOCUS_MODE_FACEDETECT;
1078 else if (strcmp(focus_mode_string, "continuous-video") == 0)
1079 focus_mode = FOCUS_MODE_CONTINOUS_VIDEO;
1080 else if (strcmp(focus_mode_string, "continuous-picture") == 0)
1081 focus_mode = FOCUS_MODE_CONTINOUS_PICTURE;
1082 else {
1083 exynos_param_string_set(exynos_camera, "focus-mode",
1084 exynos_camera->raw_focus_mode);
1085 return -EINVAL;
1086 }
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001087 }
1088
Dheeraj CVRb6f26b52014-01-11 15:35:45 +05301089 if (focus_mode != exynos_camera->focus_mode || force) {
1090 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode);
1091 if (rc < 0)
1092 ALOGE("%s: Unable to set focus mode", __func__);
1093 }
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001094
1095 exynos_camera->focus_mode = focus_mode;
1096 sprintf(exynos_camera->raw_focus_mode, "%s", focus_mode_string);
1097 }
1098
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001099 // Exposure
1100
1101 exposure_compensation = exynos_param_int_get(exynos_camera, "exposure-compensation");
1102 min_exposure_compensation = exynos_param_int_get(exynos_camera, "min-exposure-compensation");
1103 max_exposure_compensation = exynos_param_int_get(exynos_camera, "max-exposure-compensation");
1104
1105 if (exposure_compensation <= max_exposure_compensation && exposure_compensation >= min_exposure_compensation &&
1106 (exposure_compensation != exynos_camera->exposure_compensation || force)) {
1107 exynos_camera->exposure_compensation = exposure_compensation;
1108 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_BRIGHTNESS, exposure_compensation);
1109 if (rc < 0)
1110 ALOGE("%s: Unable to set exposure", __func__);
1111 }
1112
1113 // Antibanding
1114
1115 antibanding_string = exynos_param_string_get(exynos_camera, "antibanding");
1116 if (antibanding_string != NULL) {
1117 if (strcmp(antibanding_string, "auto") == 0)
1118 antibanding = ANTI_BANDING_AUTO;
1119 else if (strcmp(antibanding_string, "50hz") == 0)
1120 antibanding = ANTI_BANDING_50HZ;
1121 else if (strcmp(antibanding_string, "60hz") == 0)
1122 antibanding = ANTI_BANDING_60HZ;
1123 else if (strcmp(antibanding_string, "off") == 0)
1124 antibanding = ANTI_BANDING_OFF;
1125 else
1126 antibanding = ANTI_BANDING_AUTO;
1127
1128 if (antibanding != exynos_camera->antibanding || force) {
1129 exynos_camera->antibanding = antibanding;
1130 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ANTI_BANDING, antibanding);
1131 if (rc < 0)
1132 ALOGE("%s: Unable to set antibanding", __func__);
1133 }
1134 }
1135
1136 // WB
1137
1138 whitebalance_string = exynos_param_string_get(exynos_camera, "whitebalance");
1139 if (whitebalance_string != NULL) {
1140 if (strcmp(whitebalance_string, "auto") == 0)
1141 whitebalance = WHITE_BALANCE_AUTO;
1142 else if (strcmp(whitebalance_string, "incandescent") == 0)
1143 whitebalance = WHITE_BALANCE_TUNGSTEN;
1144 else if (strcmp(whitebalance_string, "fluorescent") == 0)
1145 whitebalance = WHITE_BALANCE_FLUORESCENT;
1146 else if (strcmp(whitebalance_string, "daylight") == 0)
1147 whitebalance = WHITE_BALANCE_SUNNY;
1148 else if (strcmp(whitebalance_string, "cloudy-daylight") == 0)
1149 whitebalance = WHITE_BALANCE_CLOUDY;
1150 else
1151 whitebalance = WHITE_BALANCE_AUTO;
1152
1153 if (whitebalance != exynos_camera->whitebalance || force) {
1154 exynos_camera->whitebalance = whitebalance;
1155 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_WHITE_BALANCE, whitebalance);
1156 if (rc < 0)
1157 ALOGE("%s: Unable to set whitebalance", __func__);
1158 }
1159 }
1160
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001161 // Effect
1162
1163 effect_string = exynos_param_string_get(exynos_camera, "effect");
1164 if (effect_string != NULL) {
1165 if (strcmp(effect_string, "auto") == 0)
1166 effect = IMAGE_EFFECT_NONE;
1167 if (strcmp(effect_string, "none") == 0)
1168 effect = IMAGE_EFFECT_NONE;
1169 else if (strcmp(effect_string, "mono") == 0)
1170 effect = IMAGE_EFFECT_BNW;
1171 else if (strcmp(effect_string, "negative") == 0)
1172 effect = IMAGE_EFFECT_NEGATIVE;
1173 else if (strcmp(effect_string, "sepia") == 0)
1174 effect = IMAGE_EFFECT_SEPIA;
1175 else if (strcmp(effect_string, "aqua") == 0)
1176 effect = IMAGE_EFFECT_AQUA;
1177 else if (strcmp(effect_string, "solarize") == 0)
1178 effect = IMAGE_EFFECT_SOLARIZE;
1179 else if (strcmp(effect_string, "posterize") == 0)
1180 effect = IMAGE_EFFECT_POSTERIZE;
1181 else if (strcmp(effect_string, "washed") == 0)
1182 effect = IMAGE_EFFECT_WASHED;
1183 else if (strcmp(effect_string, "sketch") == 0)
1184 effect = IMAGE_EFFECT_SKETCH;
1185 else if (strcmp(effect_string, "vintage-warm") == 0)
1186 effect = IMAGE_EFFECT_VINTAGE_WARM;
1187 else if (strcmp(effect_string, "vintage-cold") == 0)
1188 effect = IMAGE_EFFECT_VINTAGE_COLD;
1189 else if (strcmp(effect_string, "point-blue") == 0)
1190 effect = IMAGE_EFFECT_POINT_BLUE;
1191 else if (strcmp(effect_string, "point-red-yellow") == 0)
1192 effect = IMAGE_EFFECT_POINT_RED_YELLOW;
1193 else if (strcmp(effect_string, "point-green") == 0)
1194 effect = IMAGE_EFFECT_POINT_GREEN;
1195 else
1196 effect = IMAGE_EFFECT_NONE;
1197
1198 if (effect != exynos_camera->effect || force) {
1199 exynos_camera->effect = effect;
1200 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EFFECT, effect);
1201 if (rc < 0)
1202 ALOGE("%s: Unable to set effect", __func__);
1203 }
1204 }
1205
1206 // ISO
1207
1208 iso_string = exynos_param_string_get(exynos_camera, "iso");
1209 if (iso_string != NULL) {
1210 if (strcmp(iso_string, "auto") == 0)
1211 iso = ISO_AUTO;
1212 else if (strcmp(iso_string, "ISO50") == 0)
1213 iso = ISO_50;
1214 else if (strcmp(iso_string, "ISO100") == 0)
1215 iso = ISO_100;
1216 else if (strcmp(iso_string, "ISO200") == 0)
1217 iso = ISO_200;
1218 else if (strcmp(iso_string, "ISO400") == 0)
1219 iso = ISO_400;
1220 else if (strcmp(iso_string, "ISO800") == 0)
1221 iso = ISO_800;
1222 else
1223 iso = ISO_AUTO;
1224
1225 if (iso != exynos_camera->iso || force) {
1226 exynos_camera->iso = iso;
1227 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ISO, iso);
1228 if (rc < 0)
1229 ALOGE("%s: Unable to set iso", __func__);
1230 }
1231 }
1232
Javier Ferrer98d50c62013-09-17 23:49:39 +02001233 // Image stabilization (Anti-shake)
1234
1235 image_stabilization_string = exynos_param_string_get(exynos_camera, "image-stabilization");
1236 if (image_stabilization_string != NULL) {
1237 if (strcmp(image_stabilization_string, "on") == 0)
1238 image_stabilization = ANTI_SHAKE_STILL_ON;
1239 else
1240 image_stabilization = ANTI_SHAKE_OFF;
1241
1242 if (image_stabilization != exynos_camera->image_stabilization || force) {
1243 exynos_camera->image_stabilization = image_stabilization;
1244 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ANTI_SHAKE, image_stabilization);
1245 if (rc < 0)
1246 ALOGE("%s: Unable to set image-stabilization", __func__);
1247 }
1248 }
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001249 ALOGD("%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);
1250
1251 return 0;
1252}
1253
1254// Capture
1255
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001256int s5c73m3_interleaved_decode(struct exynos_camera *exynos_camera, void *data, int size,
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001257 void *yuv_data, int *yuv_size, int yuv_width, int yuv_height,
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001258 void *jpeg_data, int *jpeg_size, int *decoded, int *auto_focus_result,
1259 struct exynos_exif *exif)
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001260{
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001261 exif_attribute_t *attributes;
1262 camera_face_t caface[exynos_camera->max_detected_faces];
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001263 int yuv_length;
1264 int jpeg_length;
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001265 int num_detected_faces;
1266 int face;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001267 unsigned char *yuv_p;
1268 unsigned char *jpeg_p;
1269 unsigned char *data_p;
1270 unsigned int *offset_p;
1271 unsigned int pointers_array_offset;
1272 unsigned int pointers_array_size;
1273 unsigned int interleaved_size;
1274 unsigned char s5c73m3_auto_focus_result;
1275 unsigned int yuv_offset_last;
1276 unsigned int yuv_offset;
1277 unsigned int yuv_line_size;
1278 unsigned short *jpeg_start_p;
1279 int gap;
1280 unsigned int i;
1281
1282 if (data == NULL || size <= 0 || yuv_data == NULL || yuv_size == NULL || yuv_width <= 0 || yuv_height <= 0 || jpeg_data == NULL || jpeg_size == NULL || decoded == NULL || auto_focus_result == NULL)
1283 return -EINVAL;
1284
1285 yuv_length = 0;
1286 jpeg_length = 0;
1287
1288 data_p = (unsigned char *) data;
1289 data_p += size - 0x1000; // End of the first plane (interleaved buffer)
1290 data_p += 4046; // Experimental offset for decoded
1291
1292 *decoded = (int) *data_p;
1293
1294 data_p = (unsigned char *) data;
1295 data_p += size - 0x1000; // End of the first plane (interleaved buffer)
1296 data_p += 50; // Experimental offset for auto-focus result
1297
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001298 *auto_focus_result = (int) *data_p;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001299
1300 data_p = (unsigned char *) data;
1301 data_p += size - 0x1000; // End of the first plane (interleaved buffer)
1302 data_p += 4084; // Experimental offset for interleaved size
1303
1304 // Read the pointers array offset
1305 offset_p = (unsigned int *) data_p;
1306 pointers_array_offset = BIG2LITTLE_ENDIAN(*offset_p);
1307 interleaved_size = pointers_array_offset;
1308
1309 // Read the pointers array size, it should be 4 * yuv_height
1310 data_p += sizeof(pointers_array_offset);
1311 offset_p = (unsigned int *) data_p;
1312 pointers_array_size = BIG2LITTLE_ENDIAN(*offset_p);
1313
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001314 // FaceDetection Information
1315 data_p = (unsigned char *) data;
1316 data_p += size - 0x1000; // End of the first plane (interleaved buffer)
1317 data_p += 108; //Number of Faces Detected
1318
1319 num_detected_faces = (int) *data_p;
1320 data_p += 2; //Start of Face Detection Info
1321
1322 exynos_camera->mFaceData.faces = caface;
1323 if (num_detected_faces > 0 && num_detected_faces < exynos_camera->max_detected_faces)
1324 {
1325 for (face = 0; face < num_detected_faces; face++) {
1326 exynos_camera->mFaceData.faces[face].rect[0] = (short)(data_p[1] << 8) + data_p[0];
1327 data_p += 2;
1328 exynos_camera->mFaceData.faces[face].rect[1] = (short)(data_p[1] << 8) + data_p[0];
1329 data_p += 2;
1330 exynos_camera->mFaceData.faces[face].rect[2] = (short)(data_p[1] << 8) + data_p[0];
1331 data_p += 2;
1332 exynos_camera->mFaceData.faces[face].rect[3] = (short)(data_p[1] << 8) + data_p[0];
1333 data_p += 2;
1334 exynos_camera->mFaceData.faces[face].score = (short)(data_p[1] << 8) + data_p[0];
1335 data_p += 2;
1336 exynos_camera->mFaceData.faces[face].id = (short)(data_p[1] << 8) + data_p[0];
1337 data_p += 2;
1338 }
1339 }
1340 exynos_camera->mFaceData.number_of_faces = num_detected_faces;
1341
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001342 if (!*decoded)
1343 return 0;
1344
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001345 attributes = &exif->attributes;
1346
1347 //Extract the EXIF from the Metadata
1348 //Flash
1349 data_p = (unsigned char *) data;
1350 data_p += size - 0x1000; // End of the first plane (interleaved buffer)
1351 data_p += 4; // EXIF Flash Offset
1352 attributes->flash = (int) data_p[0];
1353
1354 //ISO
1355 data_p += 4; // EXIF ISO Offset
1356 attributes->iso_speed_rating = (data_p[1] << 8) + data_p[0];
1357
1358 //Exposure
1359 data_p += 4; // EXIF Exposure Offset
1360 attributes->brightness.num = (int) data_p[0];
1361
1362 //Exposure Bias
1363 data_p += 4; // EXIF Exposure Bias Offset
1364 attributes->exposure_bias.num = (data_p[1] << 8) + data_p[0];
1365
1366 //Exposure Time
1367 data_p += 8; // EXIF Exposure Time Offset
1368 attributes->exposure_time.den = (data_p[1] << 8) + data_p[0];
1369
1370
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001371 ALOGD("%s: Interleaved pointers array is at offset 0x%x, 0x%x bytes long\n", __func__, pointers_array_offset, pointers_array_size);
1372
1373 if ((int) pointers_array_offset > size || (int) pointers_array_size > size || (int) pointers_array_size < yuv_height * (int) sizeof(unsigned int)) {
1374 ALOGE("%s: Invalid informations", __func__);
1375 return -1;
1376 }
1377
1378 data_p = (unsigned char *) data;
1379 data_p += pointers_array_offset;
1380 yuv_p = (unsigned char *) yuv_data;
1381 jpeg_p = (unsigned char *) jpeg_data;
1382 jpeg_start_p = NULL;
1383
1384 yuv_line_size = yuv_width * 2;
1385 yuv_offset_last = 0;
1386 yuv_offset = 0;
1387 i = 0;
1388
1389 while (i < pointers_array_size) {
1390 offset_p = (unsigned int *) data_p;
1391 yuv_offset = BIG2LITTLE_ENDIAN(*offset_p);
1392
1393 if (yuv_offset > size - yuv_line_size)
1394 return -1;
1395
1396 gap = yuv_offset - yuv_offset_last - yuv_line_size;
1397
1398 if (gap > 0) {
1399 data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size;
1400
1401 if (jpeg_start_p == NULL) {
1402 jpeg_start_p = (unsigned short *) data_p;
1403 if (*jpeg_start_p != 0xd8ff) {
1404 ALOGE("%s: Invalid jpeg start", __func__);
1405 return -1;
1406 }
1407 }
1408
1409 memcpy(jpeg_p, data_p, gap);
1410 jpeg_p += gap;
1411 jpeg_length += gap;
1412 }
1413
1414 yuv_offset_last = yuv_offset;
1415
1416 data_p = (unsigned char *) data + yuv_offset;
1417 memcpy(yuv_p, data_p, yuv_line_size);
1418 yuv_p += yuv_line_size;
1419 yuv_length += yuv_line_size;
1420
1421 data_p = (unsigned char *) offset_p;
1422 data_p += sizeof(yuv_offset);
1423 i += sizeof(yuv_offset);
1424 }
1425
1426 gap = interleaved_size - yuv_offset_last - yuv_line_size;
1427
1428 if (gap > 0) {
1429 data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size;
1430
1431 memcpy(jpeg_p, data_p, gap);
1432 jpeg_p += gap;
1433 jpeg_length += gap;
1434 }
1435
1436 *yuv_size = yuv_length;
1437 *jpeg_size = jpeg_length;
1438
1439 return 0;
1440}
1441
1442int exynos_camera_capture(struct exynos_camera *exynos_camera)
1443{
1444 struct exynos_camera_capture_listener *listener;
1445 struct exynos_camera_buffer *buffers = NULL;
1446 struct exynos_camera_buffer *buffer;
1447 struct list_head *list;
1448 int width, height, format;
1449 int yuv_length, jpeg_length;
1450 int jpeg_offset, jpeg_size;
1451 int jpeg_thumbnail_offset, jpeg_thumbnail_size;
1452 int buffers_count;
1453 int buffer_length;
1454 int auto_focus_result;
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001455 int current_af;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001456 int decoded;
1457 int busy;
1458 void *pointer;
1459 int address;
1460 int offset;
1461 int index;
1462 int rc;
1463
1464 if (exynos_camera == NULL)
1465 return -EINVAL;
1466
1467 width = exynos_camera->capture_width;
1468 height = exynos_camera->capture_height;
1469 format = exynos_camera->capture_format;
1470
1471 buffers_count = exynos_camera->capture_buffers_count;
1472 buffer_length = exynos_camera->capture_buffer_length;
1473
1474 // V4L2
1475
1476 index = exynos_v4l2_dqbuf_cap(exynos_camera, 0);
1477 if (index < 0 || index >= buffers_count) {
1478 rc = exynos_v4l2_poll(exynos_camera, 0);
1479 if (rc < 0) {
1480 ALOGE("%s Unable to poll", __func__);
1481 goto error;
1482 } else if (rc == 0) {
1483 // Timeout
1484 rc = 0;
1485 goto complete;
1486 }
1487
1488 index = exynos_v4l2_dqbuf_cap(exynos_camera, 0);
1489 if (index < 0 || index >= buffers_count) {
1490 ALOGE("%s: Unable to dequeue buffer", __func__);
1491 goto error;
1492 }
1493 }
1494
1495 exynos_camera->capture_memory_index = index;
1496
1497 address = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, index);
1498 if (address == 0 || address == (int) 0xffffffff) {
1499 ALOGE("%s: Unable to get address", __func__);
1500 goto error;
1501 }
1502
1503 offset = address - exynos_camera->capture_memory_address;
1504 if (offset != index * buffer_length)
1505 ALOGE("%s: Inconsistent memory offset (0x%x/0x%x)", __func__, offset, index * buffer_length);
1506
1507 pointer = (void *) ((unsigned char *) exynos_camera->capture_memory->data + offset);
1508
1509 // Buffers
1510
1511 switch (format) {
1512 case V4L2_PIX_FMT_INTERLEAVED:
1513 yuv_length = jpeg_length = 0;
1514 auto_focus_result = decoded = 0;
1515
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001516 rc = s5c73m3_interleaved_decode(exynos_camera, pointer, buffer_length, exynos_camera->capture_yuv_buffer, &yuv_length, width, height, exynos_camera->capture_jpeg_buffer, &jpeg_length, &decoded, &auto_focus_result, &exynos_camera->exif);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001517 if (rc < 0) {
1518 ALOGE("%s: Unable to decode S5C73M3 interleaved", __func__);
1519 goto error;
1520 }
1521
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001522 // AutoFocus
1523 switch (auto_focus_result) {
1524 case S5C73M3_CAF_STATUS_FOCUSING:
1525 case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR:
1526 case S5C73M3_AF_STATUS_FOCUSING:
1527 current_af = CAMERA_AF_STATUS_IN_PROGRESS;
1528 break;
1529 case S5C73M3_CAF_STATUS_FOCUSED:
1530 case S5C73M3_AF_STATUS_FOCUSED:
1531 current_af = CAMERA_AF_STATUS_SUCCESS;
1532 break;
1533 case S5C73M3_CAF_STATUS_UNFOCUSED:
1534 case S5C73M3_AF_STATUS_UNFOCUSED:
1535 current_af = CAMERA_AF_STATUS_FAIL;
1536 break;
1537 case S5C73M3_AF_STATUS_INVALID:
1538 default:
1539 current_af = CAMERA_AF_STATUS_RESTART;
1540 }
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001541
Dheeraj CVRfecfc162013-12-29 13:41:48 +05301542 if (exynos_camera->auto_focus_enabled) {
1543 rc = exynos_camera_auto_focus(exynos_camera, current_af);
1544 if (rc < 0) {
1545 ALOGE("%s: Unable to auto focus", __func__);
1546 goto error;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001547 }
1548 }
1549
Dheeraj CVRa533cbc2014-01-11 15:10:10 +05301550 // CAF
1551 switch (auto_focus_result) {
1552 case S5C73M3_CAF_STATUS_FOCUSING:
1553 case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR:
1554 current_af = CAMERA_AF_STATUS_IN_PROGRESS;
1555 break;
1556 case S5C73M3_CAF_STATUS_FOCUSED:
1557 current_af = CAMERA_AF_STATUS_SUCCESS;
1558 break;
1559 case S5C73M3_CAF_STATUS_UNFOCUSED:
1560 default:
1561 current_af = CAMERA_AF_STATUS_RESTART;
1562 }
1563
1564 rc = exynos_camera_continuous_auto_focus(exynos_camera, current_af);
1565 if (rc < 0) {
1566 ALOGE("%s: Unable to continuous auto focus", __func__);
1567 goto error;
1568 }
1569
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001570 if (!decoded) {
1571 buffers_count = 1;
1572 buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer));
1573
1574 buffer = buffers;
1575
1576 buffer->pointer = pointer;
1577 buffer->address = address;
1578 buffer->length = exynos_camera_buffer_length(width, height, V4L2_PIX_FMT_UYVY);
1579 buffer->width = width;
1580 buffer->height = height;
1581 buffer->format = V4L2_PIX_FMT_UYVY;
1582 } else {
1583 buffers_count = 2;
1584 buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer));
1585
1586 buffer = buffers;
1587
1588 memcpy(pointer, exynos_camera->capture_yuv_buffer, yuv_length);
1589
1590 buffer->pointer = pointer;
1591 buffer->address = address;
1592 buffer->length = yuv_length;
1593 buffer->width = width;
1594 buffer->height = height;
1595 buffer->format = V4L2_PIX_FMT_UYVY;
1596
1597 pointer = (void *) ((unsigned char *) pointer + yuv_length);
1598 address += yuv_length;
1599 buffer = (struct exynos_camera_buffer *) ((unsigned char *) buffer + sizeof(struct exynos_camera_buffer));
1600
1601 memcpy(pointer, exynos_camera->capture_jpeg_buffer, jpeg_length);
1602
1603 buffer->pointer = pointer;
1604 buffer->address = address;
1605 buffer->length = jpeg_length;
1606 buffer->width = exynos_camera->picture_width;
1607 buffer->height = exynos_camera->picture_height;
1608 buffer->format = V4L2_PIX_FMT_JPEG;
1609
1610 exynos_camera->capture_hybrid = 0;
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001611
1612 exynos_exif_create(exynos_camera, &exynos_camera->exif);
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001613 }
1614 break;
1615 case V4L2_PIX_FMT_JPEG:
1616 jpeg_size = jpeg_offset = 0;
1617 jpeg_thumbnail_size = jpeg_thumbnail_offset = 0;
1618
1619 rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_MAIN_SIZE, &jpeg_size);
1620 if (rc < 0 || jpeg_size <= 0) {
1621 ALOGE("%s: Unable to get jpeg size", __func__);
1622 goto error;
1623 }
1624
1625 rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_MAIN_OFFSET, &jpeg_offset);
1626 if (rc < 0) {
1627 ALOGE("%s: Unable to get jpeg offset", __func__);
1628 goto error;
1629 }
1630
1631 rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_THUMB_SIZE, &jpeg_thumbnail_size);
1632 if (rc < 0 || jpeg_thumbnail_size <= 0) {
1633 ALOGE("%s: Unable to get jpeg thumbnail size", __func__);
1634 goto error;
1635 }
1636
1637 rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_THUMB_OFFSET, &jpeg_thumbnail_offset);
1638 if (rc < 0) {
1639 ALOGE("%s: Unable to get jpeg thumbnail offset", __func__);
1640 goto error;
1641 }
1642
1643 buffers_count = 2;
1644 buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer));
1645
1646 buffer = buffers;
1647
1648 buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_offset);
1649 buffer->address = address + jpeg_offset;
1650 buffer->length = jpeg_size;
1651 buffer->width = exynos_camera->picture_width;
1652 buffer->height = exynos_camera->picture_height;
1653 buffer->format = V4L2_PIX_FMT_JPEG;
1654
1655 buffer = (struct exynos_camera_buffer *) ((unsigned char *) buffer + sizeof(struct exynos_camera_buffer));
1656
1657 buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_thumbnail_offset);
1658 buffer->address = address + jpeg_thumbnail_offset;
1659 buffer->length = jpeg_thumbnail_size;
1660 buffer->width = exynos_camera->jpeg_thumbnail_width;
1661 buffer->height = exynos_camera->jpeg_thumbnail_height;
1662 buffer->format = V4L2_PIX_FMT_JPEG;
Dheeraj CVRa50844d2013-12-14 10:54:53 -06001663
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02001664 break;
1665 default:
1666 buffers_count = 1;
1667 buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer));
1668
1669 buffer = buffers;
1670
1671 buffer->pointer = pointer;
1672 buffer->address = address;
1673 buffer->length = buffer_length;
1674 buffer->width = width;
1675 buffer->height = height;
1676 buffer->format = format;
1677 break;
1678 }
1679
1680 // Listeners
1681
1682 list = (struct list_head *) exynos_camera->capture_listeners;
1683 while (list != NULL) {
1684 listener = (struct exynos_camera_capture_listener *) list;
1685
1686 if (listener->callback == NULL)
1687 goto list_continue_callback;
1688
1689 /*
1690 * Callback must never call a capture-locked function or it will
1691 * block. Hence, do not unregister the listener in callback.
1692 */
1693
1694 listener->callback(exynos_camera, buffers, buffers_count);
1695
1696list_continue_callback:
1697 list = list->next;
1698 }
1699
1700 do {
1701 busy = 0;
1702
1703 list = (struct list_head *) exynos_camera->capture_listeners;
1704 while (list != NULL) {
1705 listener = (struct exynos_camera_capture_listener *) list;
1706
1707 if (listener->callback == NULL)
1708 goto list_continue_busy;
1709
1710 busy |= listener->busy;
1711
1712list_continue_busy:
1713 list = list->next;
1714 }
1715
1716 if (busy)
1717 usleep(1000);
1718 } while (busy);
1719
1720 rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, index);
1721 if (rc < 0) {
1722 ALOGE("%s: Unable to queue buffer", __func__);
1723 goto error;
1724 }
1725
1726 rc = 0;
1727 goto complete;
1728
1729error:
1730 rc = -1;
1731
1732complete:
1733 if (buffers != NULL)
1734 free(buffers);
1735
1736 return rc;
1737}
1738
1739void *exynos_camera_capture_thread(void *data)
1740{
1741 struct exynos_camera *exynos_camera;
1742 int rc;
1743
1744 if (data == NULL)
1745 return NULL;
1746
1747 exynos_camera = (struct exynos_camera *) data;
1748
1749 ALOGE("%s: Starting thread", __func__);
1750 exynos_camera->capture_thread_running = 1;
1751
1752 while (exynos_camera->capture_thread_enabled) {
1753 pthread_mutex_lock(&exynos_camera->capture_lock_mutex);
1754
1755 while (exynos_camera->capture_enabled) {
1756 pthread_mutex_lock(&exynos_camera->capture_mutex);
1757
1758 if (!exynos_camera->capture_enabled) {
1759 pthread_mutex_unlock(&exynos_camera->capture_mutex);
1760 break;
1761 }
1762
1763 rc = exynos_camera_capture(exynos_camera);
1764 if (rc < 0) {
1765 ALOGE("%s: Unable to capture", __func__);
1766 pthread_mutex_unlock(&exynos_camera->capture_mutex);
1767 break;
1768 }
1769
1770 pthread_mutex_unlock(&exynos_camera->capture_mutex);
1771
1772 // Wait a bit to let others lock the mutex if they need to
1773 usleep(10);
1774 }
1775 }
1776
1777 exynos_camera->capture_thread_running = 0;
1778 ALOGE("%s: Exiting thread", __func__);
1779
1780 return NULL;
1781}
1782
1783int exynos_camera_capture_thread_start(struct exynos_camera *exynos_camera)
1784{
1785 pthread_attr_t thread_attr;
1786 int rc;
1787
1788 if (exynos_camera == NULL)
1789 return -EINVAL;
1790
1791 ALOGD("%s()", __func__);
1792
1793 if (exynos_camera->capture_thread_enabled) {
1794 ALOGE("Capture thread was already started!");
1795 return -1;
1796 }
1797
1798 pthread_mutex_init(&exynos_camera->capture_mutex, NULL);
1799 pthread_mutex_init(&exynos_camera->capture_lock_mutex, NULL);
1800
1801 // Initial lock
1802 pthread_mutex_lock(&exynos_camera->capture_lock_mutex);
1803
1804 pthread_attr_init(&thread_attr);
1805 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
1806
1807 exynos_camera->capture_thread_enabled = 1;
1808
1809 rc = pthread_create(&exynos_camera->capture_thread, &thread_attr, exynos_camera_capture_thread, (void *) exynos_camera);
1810 if (rc < 0) {
1811 ALOGE("%s: Unable to create thread", __func__);
1812 goto error;
1813 }
1814
1815 rc = 0;
1816 goto complete;
1817
1818error:
1819 pthread_mutex_destroy(&exynos_camera->capture_mutex);
1820 pthread_mutex_destroy(&exynos_camera->capture_lock_mutex);
1821
1822 rc = -1;
1823
1824complete:
1825 return rc;
1826}
1827
1828void exynos_camera_capture_thread_stop(struct exynos_camera *exynos_camera)
1829{
1830 int i;
1831
1832 if (exynos_camera == NULL)
1833 return;
1834
1835 ALOGD("%s()", __func__);
1836
1837 if (!exynos_camera->capture_thread_enabled) {
1838 ALOGE("Capture thread was already stopped!");
1839 return;
1840 }
1841
1842 exynos_camera->capture_enabled = 0;
1843 exynos_camera->capture_thread_enabled = 0;
1844
1845 pthread_mutex_unlock(&exynos_camera->capture_lock_mutex);
1846
1847 // Wait for the thread to end
1848 i = 0;
1849 while (exynos_camera->capture_thread_running) {
1850 if (i++ > 10000) {
1851 ALOGE("Capture thread is taking too long to end, something is going wrong");
1852 break;
1853 }
1854 usleep(100);
1855 }
1856
1857 if (exynos_camera->capture_enabled) {
1858 pthread_mutex_lock(&exynos_camera->capture_mutex);
1859 exynos_camera_capture_stop(exynos_camera);
1860 pthread_mutex_unlock(&exynos_camera->capture_mutex);
1861 }
1862
1863 pthread_mutex_destroy(&exynos_camera->capture_mutex);
1864 pthread_mutex_destroy(&exynos_camera->capture_lock_mutex);
1865}
1866
1867int exynos_camera_capture_start(struct exynos_camera *exynos_camera)
1868{
1869 struct v4l2_streamparm fps_param;
1870 int width, height, format;
1871 int mbus_width, mbus_height;
1872 int buffers_count, buffer_length;
1873 camera_memory_t *memory = NULL;
1874 int value;
1875 int fd;
1876 int rc;
1877 int i;
1878
1879 if (exynos_camera == NULL)
1880 return -EINVAL;
1881
1882 ALOGD("%s()", __func__);
1883
1884 if (exynos_camera->capture_enabled) {
1885 ALOGE("Capture was already started!");
1886 return -1;
1887 }
1888
1889 width = exynos_camera->capture_width;
1890 height = exynos_camera->capture_height;
1891 format = exynos_camera->capture_format;
1892
1893 // V4L2
1894
1895 if (format == V4L2_PIX_FMT_INTERLEAVED) {
1896 ALOGD("Enabling hybrid capture");
1897 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_HYBRID, 1);
1898 if (rc < 0) {
1899 ALOGE("%s: Unable to set hybrid", __func__);
1900 goto error;
1901 }
1902 }
1903
1904 if (exynos_camera->camera_fimc_is) {
1905 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, exynos_camera->fimc_is_mode);
1906 if (rc < 0) {
1907 ALOGE("%s: Unable to set FIMC-IS scenario", __func__);
1908 goto error;
1909 }
1910 }
1911
1912 rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, format);
1913 if (rc < 0) {
1914 ALOGE("%s: Unable to enumerate formats", __func__);
1915 goto error;
1916 }
1917
1918 mbus_width = width;
1919 mbus_height = height;
1920
1921 if (exynos_camera->camera_mbus_resolutions != NULL) {
1922 for (i = 0; i < exynos_camera->camera_mbus_resolutions_count; i++) {
1923 if (exynos_camera->camera_mbus_resolutions[i].width == width && exynos_camera->camera_mbus_resolutions[i].height == height) {
1924 mbus_width = exynos_camera->camera_mbus_resolutions[i].mbus_width;
1925 mbus_height = exynos_camera->camera_mbus_resolutions[i].mbus_height;
1926 break;
1927 }
1928 }
1929 }
1930
1931 if (exynos_camera->camera_fimc_is) {
1932 // Set MBUS width/height/format
1933 rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, exynos_camera->fimc_is_mode, V4L2_PIX_FMT_MODE_PREVIEW);
1934 if (rc < 0) {
1935 ALOGE("%s: Unable to set MBUS capture pixel format", __func__);
1936 goto error;
1937 }
1938 }
1939
1940 rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_PREVIEW);
1941 if (rc < 0) {
1942 ALOGE("%s: Unable to set capture pixel format", __func__);
1943 goto error;
1944 }
1945
1946 if (!exynos_camera->camera_fimc_is) {
1947 // Set MBUS width/height/format
1948 rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, V4L2_FIELD_NONE, V4L2_PIX_FMT_MODE_PREVIEW);
1949 if (rc < 0) {
1950 ALOGE("%s: Unable to set MBUS capture pixel format", __func__);
1951 goto error;
1952 }
1953 }
1954
1955 if (format == V4L2_PIX_FMT_INTERLEAVED)
1956 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CACHEABLE, 0);
1957 else
1958 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CACHEABLE, 1);
1959 if (rc < 0) {
1960 ALOGE("%s: Unable to set cacheable", __func__);
1961 goto error;
1962 }
1963
1964 if (exynos_camera->camera_fimc_is) {
1965 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_SCENARIO_MODE, exynos_camera->fimc_is_mode);
1966 if (rc < 0) {
1967 ALOGE("%s: Unable to set FIMC-IS scenario mode", __func__);
1968 goto error;
1969 }
1970 }
1971
1972 if (format == V4L2_PIX_FMT_INTERLEAVED) {
1973 // This must be set to 1 for interleaved data decoding
1974 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_EMBEDDEDDATA_ENABLE, 1);
1975 if (rc < 0) {
1976 ALOGE("%s: Unable to set embdedded data enable", __func__);
1977 goto error;
1978 }
1979 }
1980
1981 // Let's assume FIMC0 has memory available through mmap
1982
1983 for (i = EXYNOS_CAMERA_CAPTURE_BUFFERS_COUNT; i > 0; i--) {
1984 rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, i);
1985 if (rc >= 0)
1986 break;
1987 }
1988
1989 if (rc < 0) {
1990 ALOGE("%s: Unable to request buffers", __func__);
1991 goto error;
1992 }
1993
1994 buffers_count = rc;
1995 ALOGD("Found %d buffers available for capture!", buffers_count);
1996
1997 memset(&fps_param, 0, sizeof(fps_param));
1998 fps_param.parm.capture.timeperframe.numerator = 1;
1999 fps_param.parm.capture.timeperframe.denominator = exynos_camera->preview_fps;
2000
2001 rc = exynos_v4l2_s_parm_cap(exynos_camera, 0, &fps_param);
2002 if (rc < 0) {
2003 ALOGE("%s: Unable to set fps", __func__);
2004 goto error;
2005 }
2006
2007 for (i = 0; i < buffers_count; i++) {
2008 rc = exynos_v4l2_querybuf_cap(exynos_camera, 0, i);
2009 if (rc < 0) {
2010 ALOGE("%s: Unable to query buffers", __func__);
2011 goto error;
2012 }
2013 }
2014
2015 buffer_length = rc;
2016
2017 value = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, 0);
2018 if (value == 0 || value == (int) 0xffffffff) {
2019 ALOGE("%s: Unable to get address", __func__);
2020 goto error;
2021 }
2022
2023 exynos_camera->capture_memory_address = value;
2024
2025 if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) {
2026 fd = exynos_v4l2_fd(exynos_camera, 0);
2027 if (fd < 0) {
2028 ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, 0);
2029 goto error;
2030 }
2031
2032 exynos_camera->capture_memory = NULL;
2033
2034 memory = exynos_camera->callbacks.request_memory(fd, buffer_length, buffers_count, exynos_camera->callbacks.user);
2035 if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) {
2036 ALOGE("%s: Unable to request memory", __func__);
2037 goto error;
2038 }
2039
2040 exynos_camera->capture_memory = memory;
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002041
2042 memory = exynos_camera->callbacks.request_memory(-1, 1, 1, exynos_camera->callbacks.user);
2043
2044 exynos_camera->face_data = memory;
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002045 } else {
2046 ALOGE("%s: No memory request function!", __func__);
2047 goto error;
2048 }
2049
2050 if (format == V4L2_PIX_FMT_INTERLEAVED) {
2051 exynos_camera->capture_yuv_buffer = malloc(buffer_length);
2052 exynos_camera->capture_jpeg_buffer = malloc(buffer_length);
2053 }
2054
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002055 // Start EXIF
2056 memset(&exynos_camera->exif, 0, sizeof(exynos_camera->exif));
2057 exynos_exif_start(exynos_camera, &exynos_camera->exif);
2058
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002059 for (i = 0; i < buffers_count; i++) {
2060 rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, i);
2061 if (rc < 0) {
2062 ALOGE("%s: Unable to queue buffer", __func__);
2063 goto error;
2064 }
2065 }
2066
2067 exynos_camera->capture_buffers_count = buffers_count;
2068 exynos_camera->capture_buffer_length = buffer_length;
2069
2070 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_ROTATION,
2071 exynos_camera->camera_rotation);
2072 if (rc < 0) {
2073 ALOGE("%s: Unable to set rotation", __func__);
2074 goto error;
2075 }
2076
2077 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_HFLIP,
2078 exynos_camera->camera_hflip);
2079 if (rc < 0) {
2080 ALOGE("%s: Unable to set hflip", __func__);
2081 goto error;
2082 }
2083
2084 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_VFLIP,
2085 exynos_camera->camera_vflip);
2086 if (rc < 0) {
2087 ALOGE("%s: Unable to set vflip", __func__);
2088 goto error;
2089 }
2090
2091 rc = exynos_v4l2_streamon_cap(exynos_camera, 0);
2092 if (rc < 0) {
2093 ALOGE("%s: Unable to start stream", __func__);
2094 goto error;
2095 }
2096
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002097 // Few Scene Modes require to be set after stream on
2098 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, exynos_camera->scene_mode);
2099 if (rc < 0) {
2100 ALOGE("%s: Unable to set scene mode", __func__);
2101 goto error;
2102 }
2103
2104 if (exynos_camera->camera_fimc_is) {
2105 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_START);
2106 if (rc < 0) {
2107 ALOGE("%s: Unable to start face detection", __func__);
2108 goto error;
2109 }
2110 }
2111
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002112 exynos_camera->capture_enabled = 1;
2113 pthread_mutex_unlock(&exynos_camera->capture_lock_mutex);
2114
2115 rc = 0;
2116 goto complete;
2117
2118error:
Dheeraj CVR7998a462014-03-24 07:16:42 +05302119 if (exynos_camera->face_data != NULL && exynos_camera->face_data->release != NULL) {
2120 exynos_camera->face_data->release(exynos_camera->face_data);
2121 exynos_camera->face_data = NULL;
2122 }
2123
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002124 if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) {
2125 exynos_camera->capture_memory->release(exynos_camera->capture_memory);
2126 exynos_camera->capture_memory = NULL;
2127 }
2128
2129 rc = -1;
2130
2131complete:
2132 return rc;
2133}
2134
2135void exynos_camera_capture_stop(struct exynos_camera *exynos_camera)
2136{
2137 int rc;
2138 int i;
2139
2140 if (exynos_camera == NULL)
2141 return;
2142
2143 ALOGD("%s()", __func__);
2144
2145 if (!exynos_camera->capture_enabled) {
2146 ALOGE("Capture was already stopped!");
2147 return;
2148 }
2149
2150 if (exynos_camera->capture_format == V4L2_PIX_FMT_INTERLEAVED) {
2151 ALOGD("Disabling hybrid capture");
2152 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_HYBRID, 0);
2153 if (rc < 0)
2154 ALOGE("%s: Unable to set hybrid", __func__);
2155 }
2156
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002157 if (exynos_camera->camera_fimc_is) {
2158 rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_STOP);
2159 if (rc < 0)
2160 ALOGE("%s: Unable to stop face detection", __func__);
2161 }
2162
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002163 rc = exynos_v4l2_streamoff_cap(exynos_camera, 0);
2164 if (rc < 0) {
2165 ALOGE("%s: Unable to stop stream", __func__);
2166 }
2167
Dheeraj CVR7998a462014-03-24 07:16:42 +05302168 if (exynos_camera->face_data != NULL && exynos_camera->face_data->release != NULL) {
2169 exynos_camera->face_data->release(exynos_camera->face_data);
2170 exynos_camera->face_data = NULL;
2171 }
2172
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002173 if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) {
2174 exynos_camera->capture_memory->release(exynos_camera->capture_memory);
2175 exynos_camera->capture_memory = NULL;
2176 }
2177
2178 if (exynos_camera->capture_yuv_buffer != NULL) {
2179 free(exynos_camera->capture_yuv_buffer);
2180 exynos_camera->capture_yuv_buffer = NULL;
2181 }
2182
2183 if (exynos_camera->capture_jpeg_buffer != NULL) {
2184 free(exynos_camera->capture_jpeg_buffer);
2185 exynos_camera->capture_jpeg_buffer = NULL;
2186 }
2187
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002188 if (&exynos_camera->exif != NULL) {
2189 exynos_exif_stop(exynos_camera, &exynos_camera->exif);
2190 free(&exynos_camera->exif);
2191 }
2192
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002193 exynos_camera->capture_enabled = 0;
2194}
2195
2196int exynos_camera_capture_setup(struct exynos_camera *exynos_camera)
2197{
2198 struct exynos_camera_capture_listener *listener;
2199 struct list_head *list;
2200 int width, height, format;
2201 int rc;
2202
2203 if (exynos_camera == NULL)
2204 return -EINVAL;
2205
2206 ALOGD("%s()", __func__);
2207
2208 // No listener left
2209 if (exynos_camera->capture_listeners == NULL && exynos_camera->capture_enabled) {
2210 exynos_camera_capture_stop(exynos_camera);
2211 return 0;
2212 }
2213
2214 width = height = format = 0;
2215
2216 list = (struct list_head *) exynos_camera->capture_listeners;
2217 while (list != NULL) {
2218 listener = (struct exynos_camera_capture_listener *) list;
2219
2220 // Interleaved format already has the correct width and height for picture set through ioctl
2221 if (exynos_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED)
2222 if (listener->format == V4L2_PIX_FMT_JPEG || listener->format == V4L2_PIX_FMT_INTERLEAVED)
2223 goto list_continue;
2224
2225 if (listener->width >= width && listener->height >= height) {
2226 width = listener->width;
2227 height = listener->height;
2228 format = listener->format;
2229 }
2230
2231list_continue:
2232 list = list->next;
2233 }
2234
2235 // Override the capture format
2236 if (exynos_camera->camera_capture_format)
2237 format = exynos_camera->camera_capture_format;
2238
2239 // Only picture is listening, but we need some preview size anyway
2240 if (format == V4L2_PIX_FMT_INTERLEAVED && (width == 0 || height == 0)) {
2241 width = exynos_camera->preview_width;
2242 height = exynos_camera->preview_height;
2243 }
2244
2245 ALOGD("%s: Selected width: %d, height: %d, format: 0x%x", __func__, width, height, format);
2246
2247 if (!exynos_camera->capture_enabled) {
2248 exynos_camera->capture_width = width;
2249 exynos_camera->capture_height = height;
2250 exynos_camera->capture_format = format;
2251
2252 rc = exynos_camera_capture_start(exynos_camera);
2253 if (rc < 0) {
2254 ALOGE("%s: Unable to start capture", __func__);
2255 return -1;
2256 }
2257 } else if (exynos_camera->capture_width != width || exynos_camera->capture_height != height || exynos_camera->capture_format != format) {
2258 exynos_camera_capture_stop(exynos_camera);
2259
2260 exynos_camera->capture_width = width;
2261 exynos_camera->capture_height = height;
2262 exynos_camera->capture_format = format;
2263
2264 rc = exynos_camera_capture_start(exynos_camera);
2265 if (rc < 0) {
2266 ALOGE("%s: Unable to start capture", __func__);
2267 return -1;
2268 }
2269 }
2270
2271 return 0;
2272}
2273
2274struct exynos_camera_capture_listener *exynos_camera_capture_listener_register(
2275 struct exynos_camera *exynos_camera, int width, int height, int format,
2276 int (*callback)(struct exynos_camera *exynos_camera, struct exynos_camera_buffer *buffers, int buffers_count))
2277{
2278 struct exynos_camera_capture_listener *listener = NULL;
2279 struct list_head *list_end;
2280 struct list_head *list;
2281 int rc;
2282
2283 if (exynos_camera == NULL || callback == NULL)
2284 return NULL;
2285
2286 pthread_mutex_lock(&exynos_camera->capture_mutex);
2287
2288 listener = calloc(1, sizeof(struct exynos_camera_capture_listener));
2289 if (listener == NULL)
2290 goto error;
2291
2292 listener->width = width;
2293 listener->height = height;
2294 listener->format = format;
2295 listener->callback = callback;
2296 listener->busy = 0;
2297
2298 list_end = (struct list_head *) exynos_camera->capture_listeners;
2299 while (list_end != NULL && list_end->next != NULL)
2300 list_end = list_end->next;
2301
2302 list = (struct list_head *) listener;
2303 list_head_insert(list, list_end, NULL);
2304
2305 if (exynos_camera->capture_listeners == NULL)
2306 exynos_camera->capture_listeners = listener;
2307
Dheeraj CVRa50844d2013-12-14 10:54:53 -06002308 if (!(exynos_camera->camera_fimc_is && exynos_camera->picture_thread_enabled)) {
2309 rc = exynos_camera_capture_setup(exynos_camera);
2310 if (rc < 0) {
2311 ALOGE("%s: Unable to setup capture", __func__);
2312 goto error;
2313 }
Paul Kocialkowskib31c4462013-09-01 19:22:36 +02002314 }
2315
2316 rc = 0;
2317 goto complete;
2318
2319error:
2320 listener = NULL;
2321
2322complete:
2323 pthread_mutex_unlock(&exynos_camera->capture_mutex);
2324
2325 return listener;
2326}
2327
2328void exynos_camera_capture_listener_unregister(
2329 struct exynos_camera *exynos_camera,
2330 struct exynos_camera_capture_listener *listener)
2331{
2332 struct list_head *list;
2333 int rc;
2334
2335 if (exynos_camera == NULL || listener == NULL)
2336 return;
2337
2338 pthread_mutex_lock(&exynos_camera->capture_mutex);
2339
2340 list = (struct list_head *) exynos_camera->capture_listeners;
2341 while (list != NULL) {
2342 if ((void *) list == (void *) listener) {
2343 list_head_remove(list);
2344
2345 if ((void *) list == (void *) exynos_camera->capture_listeners)
2346 exynos_camera->capture_listeners = (struct exynos_camera_capture_listener *) list->next;
2347
2348 memset(listener, 0, sizeof(struct exynos_camera_capture_listener));
2349 free(listener);
2350
2351 break;
2352 }
2353list_continue:
2354 list = list->next;
2355 }
2356
2357 rc = exynos_camera_capture_setup(exynos_camera);
2358 if (rc < 0) {
2359 ALOGE("%s: Unable to setup capture", __func__);
2360 goto complete;
2361 }
2362
2363complete:
2364 pthread_mutex_unlock(&exynos_camera->capture_mutex);
2365}
2366
2367// Preview
2368
2369int exynos_camera_preview_output_start(struct exynos_camera *exynos_camera)
2370{
2371 struct exynos_v4l2_output *output;
2372 int rc;
2373
2374 if (exynos_camera == NULL)
2375 return -EINVAL;
2376
2377 ALOGD("%s()", __func__);
2378
2379 if (exynos_camera->preview_output_enabled) {
2380 ALOGE("Preview was already started!");
2381 return -1;
2382 }
2383
2384 output = &exynos_camera->preview_output;
2385
2386 memset(output, 0, sizeof(struct exynos_v4l2_output));
2387 output->v4l2_id = 1;
2388 output->width = exynos_camera->preview_width;
2389 output->height = exynos_camera->preview_height;
2390 output->format = exynos_camera->preview_format;
2391 output->buffer_width = exynos_camera->preview_buffer.width;
2392 output->buffer_height = exynos_camera->preview_buffer.height;
2393 output->buffer_format = exynos_camera->preview_buffer.format;
2394 output->buffers_count = EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT;
2395
2396 rc = exynos_v4l2_output_start(exynos_camera, output);
2397 if (rc < 0) {
2398 ALOGE("%s: Unable to start preview output", __func__);
2399 goto error;
2400 }
2401
2402 exynos_camera->preview_output_enabled = 1;
2403
2404 rc = 0;
2405 goto complete;
2406
2407error:
2408 rc = -1;
2409
2410complete:
2411 return rc;
2412}
2413
2414void exynos_camera_preview_output_stop(struct exynos_camera *exynos_camera)
2415{
2416 struct exynos_v4l2_output *output;
2417
2418 if (exynos_camera == NULL)
2419 return;
2420
2421 ALOGD("%s()", __func__);
2422
2423 if (!exynos_camera->preview_output_enabled) {
2424 ALOGE("Preview was already stopped!");
2425 return;
2426 }
2427