blob: 0485aa9708ea139e2dc62c35dce30bb4a52a78ab [file] [log] [blame]
Jiyoung Shin9426c422012-04-02 16:22:36 -07001/*
2 * Copyright 2008, The Android Open Source Project
3 * Copyright 2010, Samsung Electronics Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed toggle an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*!
19 * \file ExynosCamera.cpp
20 * \brief source file for CAMERA HAL MODULE
21 * \author thun.hwang(thun.hwang@samsung.com)
22 * \date 2010/06/03
23 *
24 * <b>Revision History: </b>
25 * - 2011/12/31 : thun.hwang(thun.hwang@samsung.com) \n
26 * Initial version
27 *
28 * - 2012/01/18 : Sangwoo, Park(sw5771.park@samsung.com) \n
29 * Adjust Doxygen Document
30 *
31 * - 2012/02/01 : Sangwoo, Park(sw5771.park@samsung.com) \n
32 * Adjust libv4l2
33 * Adjust struct ExynosCameraInfo
34 * External ISP feature
35 *
36 * - 2012/03/14 : sangwoo.park(sw5771.park@samsung.com) \n
37 * Change file, class name to ExynosXXX.
38 */
39
40/**
41 * @page ExynosCamera
42 *
43 * @section Introduction
44 * ExynosCamera is for camera preview,takePicture and recording.
45 * (Currently libseccamera is included in Android Camera HAL(libcamera.so).
46 *
47 * @section Copyright
48 * Copyright (c) 2008-2011 Samsung Electronics Co., Ltd.All rights reserved. \n
49 * Proprietary and Confidential
50 *
51 * @image html samsung.png
52 */
53
54//#define LOG_NDEBUG 0
55#define LOG_TAG "ExynosCamera"
56
57/* FIXME: This define will be removed when functions are stable */
58//#define USE_DIS
59//#define USE_3DNR
60//#define USE_ODC
61
62#include <utils/Log.h>
63
64#include "ExynosCamera.h"
65#include "exynos_format.h"
66
67using namespace android;
68
69namespace android {
70
71ExynosCameraInfo::ExynosCameraInfo()
72{
73 previewW = 2560;
74 previewH = 1920;
75 previewColorFormat = V4L2_PIX_FMT_NV21;
76 videoW = 1920;
77 videoH = 1080;
78 prefVideoPreviewW = 640;
79 prefVideoPreviewH = 360;
80 videoColorFormat = V4L2_PIX_FMT_NV12M;
81 pictureW = 2560;
82 pictureH = 1920;
83 pictureColorFormat = V4L2_PIX_FMT_YUYV;
84 thumbnailW = 320;
85 thumbnailH = 240;
86
87 antiBandingList =
88 ExynosCamera::ANTIBANDING_OFF
89 | ExynosCamera::ANTIBANDING_50HZ
90 | ExynosCamera::ANTIBANDING_60HZ
91 | ExynosCamera::ANTIBANDING_OFF;
92 antiBanding = ExynosCamera::ANTIBANDING_OFF;
93
94 effectList =
95 ExynosCamera::EFFECT_NONE
96 | ExynosCamera::EFFECT_MONO
97 | ExynosCamera::EFFECT_NEGATIVE
98 | ExynosCamera::EFFECT_SOLARIZE
99 | ExynosCamera::EFFECT_SEPIA
100 | ExynosCamera::EFFECT_POSTERIZE
101 | ExynosCamera::EFFECT_WHITEBOARD
102 | ExynosCamera::EFFECT_BLACKBOARD
103 | ExynosCamera::EFFECT_AQUA;
104 effect = ExynosCamera::EFFECT_NONE;
105
106 flashModeList =
107 ExynosCamera::FLASH_MODE_OFF
108 | ExynosCamera::FLASH_MODE_AUTO
109 | ExynosCamera::FLASH_MODE_ON
110 | ExynosCamera::FLASH_MODE_RED_EYE
111 | ExynosCamera::FLASH_MODE_TORCH;
112 flashMode = ExynosCamera::FLASH_MODE_OFF;
113
114 focusModeList =
115 ExynosCamera::FOCUS_MODE_AUTO
116 | ExynosCamera::FOCUS_MODE_INFINITY
117 | ExynosCamera::FOCUS_MODE_MACRO
118 | ExynosCamera::FOCUS_MODE_FIXED
119 | ExynosCamera::FOCUS_MODE_EDOF
120 | ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO
121 | ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE
122 | ExynosCamera::FOCUS_MODE_TOUCH;
123 focusMode = ExynosCamera::FOCUS_MODE_AUTO;
124
125 sceneModeList =
126 ExynosCamera::SCENE_MODE_AUTO
127 | ExynosCamera::SCENE_MODE_ACTION
128 | ExynosCamera::SCENE_MODE_PORTRAIT
129 | ExynosCamera::SCENE_MODE_LANDSCAPE
130 | ExynosCamera::SCENE_MODE_NIGHT
131 | ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT
132 | ExynosCamera::SCENE_MODE_THEATRE
133 | ExynosCamera::SCENE_MODE_BEACH
134 | ExynosCamera::SCENE_MODE_SNOW
135 | ExynosCamera::SCENE_MODE_SUNSET
136 | ExynosCamera::SCENE_MODE_STEADYPHOTO
137 | ExynosCamera::SCENE_MODE_FIREWORKS
138 | ExynosCamera::SCENE_MODE_SPORTS
139 | ExynosCamera::SCENE_MODE_PARTY
140 | ExynosCamera::SCENE_MODE_CANDLELIGHT;
141 sceneMode = ExynosCamera::SCENE_MODE_AUTO;
142
143 whiteBalanceList =
144 ExynosCamera::WHITE_BALANCE_AUTO
145 | ExynosCamera::WHITE_BALANCE_INCANDESCENT
146 | ExynosCamera::WHITE_BALANCE_FLUORESCENT
147 | ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT
148 | ExynosCamera::WHITE_BALANCE_DAYLIGHT
149 | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT
150 | ExynosCamera::WHITE_BALANCE_TWILIGHT
151 | ExynosCamera::WHITE_BALANCE_SHADE;
152 whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO;
153
154 autoWhiteBalanceLockSupported = false;
155 autoWhiteBalanceLock = false;
156
157 rotation = 0;
158 minExposure = -2;
159 maxExposure = 2;
160 exposure = 0;
161
162 autoExposureLockSupported = false;
163 autoExposureLock = false;
164
165 fps = 30;
166 focalLengthNum = 9;
167 focalLengthDen = 10;
168 supportVideoStabilization = false;
169 applyVideoStabilization = false;
170 videoStabilization = false;
171 maxNumMeteringAreas = 0;
172 maxNumDetectedFaces = 0;
173 maxNumFocusAreas = 0;
174 maxZoom = ZOOM_LEVEL_MAX;
175 hwZoomSupported = false;
176 zoom = 0;
177 gpsAltitude = 0;
178 gpsLatitude = 0;
179 gpsLongitude = 0;
180 gpsTimestamp = 0;
181
182 // Additional API default Value.
183 angle = 0;
184 antiShake = false;
185 beautyShot = false;
186 brightness = 0;
187 contrast = ExynosCamera::CONTRAST_DEFAULT;
188 gamma = false;
189 hue = 2; // 2 is default;
190 iso = 0;
191 metering = ExynosCamera::METERING_MODE_CENTER;
192 objectTracking = false;
193 objectTrackingStart = false;
194 saturation = 0;
195 sharpness = 0;
196 shotMode = ExynosCamera::SHOT_MODE_SINGLE;
197 slowAE = false;
198 smartAuto = false;
199 touchAfStart = false;
200 wdr = false;
201 tdnr = false;
202 odc = false;
203}
204
205ExynosCameraInfoM5M0::ExynosCameraInfoM5M0()
206{
207 previewW = 1280;
208 previewH = 720;
209 previewColorFormat = V4L2_PIX_FMT_YVU420M;
210 videoW = 1280;
211 videoH = 720;
212 prefVideoPreviewW = 640;
213 prefVideoPreviewH = 360;
214 videoColorFormat = V4L2_PIX_FMT_NV12M;
215 pictureW = 1280;
216 pictureH = 720;
217 pictureColorFormat = V4L2_PIX_FMT_YUYV;
218 thumbnailW = 320;
219 thumbnailH = 240;
220
221 antiBandingList = ExynosCamera::ANTIBANDING_OFF;
222 antiBanding = ExynosCamera::ANTIBANDING_OFF;
223
224 effectList =
225 ExynosCamera::EFFECT_NONE
226 | ExynosCamera::EFFECT_MONO
227 | ExynosCamera::EFFECT_NEGATIVE
228 //| ExynosCamera::EFFECT_SOLARIZE
229 | ExynosCamera::EFFECT_SEPIA
230 //| ExynosCamera::EFFECT_POSTERIZE
231 //| ExynosCamera::EFFECT_WHITEBOARD
232 //| ExynosCamera::EFFECT_BLACKBOARD
233 | ExynosCamera::EFFECT_AQUA;
234 effect = ExynosCamera::EFFECT_NONE;
235
236 flashModeList =
237 ExynosCamera::FLASH_MODE_OFF
238 | ExynosCamera::FLASH_MODE_AUTO
239 | ExynosCamera::FLASH_MODE_ON
240 | ExynosCamera::FLASH_MODE_RED_EYE
241 | ExynosCamera::FLASH_MODE_TORCH;
242 flashMode = ExynosCamera::FLASH_MODE_OFF;
243
244 focusModeList =
245 ExynosCamera::FOCUS_MODE_AUTO
246 | ExynosCamera::FOCUS_MODE_INFINITY
247 | ExynosCamera::FOCUS_MODE_MACRO
248 //| ExynosCamera::FOCUS_MODE_FIXED
249 //| ExynosCamera::FOCUS_MODE_EDOF
250 //| ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO
251 //| ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE
252 //| ExynosCamera::FOCUS_MODE_TOUCH
253 ;
254 focusMode = ExynosCamera::FOCUS_MODE_AUTO;
255
256 sceneModeList =
257 ExynosCamera::SCENE_MODE_AUTO
258 //| ExynosCamera::SCENE_MODE_ACTION
259 | ExynosCamera::SCENE_MODE_PORTRAIT
260 | ExynosCamera::SCENE_MODE_LANDSCAPE
261 | ExynosCamera::SCENE_MODE_NIGHT
262 //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT
263 //| ExynosCamera::SCENE_MODE_THEATRE
264 | ExynosCamera::SCENE_MODE_BEACH
265 | ExynosCamera::SCENE_MODE_SNOW
266 | ExynosCamera::SCENE_MODE_SUNSET
267 //| ExynosCamera::SCENE_MODE_STEADYPHOTO
268 | ExynosCamera::SCENE_MODE_FIREWORKS
269 | ExynosCamera::SCENE_MODE_SPORTS
270 | ExynosCamera::SCENE_MODE_PARTY
271 | ExynosCamera::SCENE_MODE_CANDLELIGHT;
272 sceneMode = ExynosCamera::SCENE_MODE_AUTO;
273
274 whiteBalanceList =
275 ExynosCamera::WHITE_BALANCE_AUTO
276 | ExynosCamera::WHITE_BALANCE_INCANDESCENT
277 | ExynosCamera::WHITE_BALANCE_FLUORESCENT
278 //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT
279 | ExynosCamera::WHITE_BALANCE_DAYLIGHT
280 | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT
281 //| ExynosCamera::WHITE_BALANCE_TWILIGHT
282 //| ExynosCamera::WHITE_BALANCE_SHADE
283 ;
284 whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO;
285
286 autoWhiteBalanceLockSupported = false;
287 autoWhiteBalanceLock = false;
288
289 rotation = 0;
290 minExposure = -2;
291 maxExposure = 2;
292 exposure = 0;
293
294 autoExposureLockSupported = false;
295 autoExposureLock = false;
296
297 fps = 30;
298 focalLengthNum = 343;
299 focalLengthDen = 100;
300 supportVideoStabilization = false;
301 applyVideoStabilization = false;
302 videoStabilization = false;
303 maxNumMeteringAreas = 64;
304 maxNumDetectedFaces = 16;
305 maxNumFocusAreas = 2;
306 maxZoom = ZOOM_LEVEL_MAX;
307 hwZoomSupported = false;
308 zoom = 0;
309 gpsAltitude = 0;
310 gpsLatitude = 0;
311 gpsLongitude = 0;
312 gpsTimestamp = 0;
313}
314
315ExynosCameraInfoS5K6A3::ExynosCameraInfoS5K6A3()
316{
317 previewW = 1280;
318 previewH = 720;
319 previewColorFormat = V4L2_PIX_FMT_YVU420M;
320 videoW = 1280;
321 videoH = 720;
322 prefVideoPreviewW = 640;
323 prefVideoPreviewH = 360;
324 videoColorFormat = V4L2_PIX_FMT_NV12M;
325 pictureW = 1280;
326 pictureH = 720;
327 pictureColorFormat = V4L2_PIX_FMT_YUYV;
328 thumbnailW = 320;
329 thumbnailH = 240;
330
331 antiBandingList =
332 ExynosCamera::ANTIBANDING_OFF
333 | ExynosCamera::ANTIBANDING_50HZ
334 | ExynosCamera::ANTIBANDING_60HZ
335 | ExynosCamera::ANTIBANDING_OFF;
336 antiBanding = ExynosCamera::ANTIBANDING_OFF;
337
338 effectList =
339 ExynosCamera::EFFECT_NONE
340 | ExynosCamera::EFFECT_MONO
341 | ExynosCamera::EFFECT_NEGATIVE
342 //| ExynosCamera::EFFECT_SOLARIZE
343 | ExynosCamera::EFFECT_SEPIA
344 //| ExynosCamera::EFFECT_POSTERIZE
345 //| ExynosCamera::EFFECT_WHITEBOARD
346 //| ExynosCamera::EFFECT_BLACKBOARD
347 //| ExynosCamera::EFFECT_AQUA
348 ;
349 effect = ExynosCamera::EFFECT_NONE;
350
351 flashModeList =
352 ExynosCamera::FLASH_MODE_OFF
353 //| ExynosCamera::FLASH_MODE_AUTO
354 //| ExynosCamera::FLASH_MODE_ON
355 //| ExynosCamera::FLASH_MODE_RED_EYE
356 //| ExynosCamera::FLASH_MODE_TORCH
357 ;
358 flashMode = ExynosCamera::FLASH_MODE_OFF;
359
360 focusModeList =
361 // ExynosCamera::FOCUS_MODE_AUTO
362 //| ExynosCamera::FOCUS_MODE_INFINITY
363 //| ExynosCamera::FOCUS_MODE_MACRO
364 //|
365 ExynosCamera::FOCUS_MODE_FIXED
366 //| ExynosCamera::FOCUS_MODE_EDOF
367 //| ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO
368 //| ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE
369 //| ExynosCamera::FOCUS_MODE_TOUCH
370 ;
371 focusMode = ExynosCamera::FOCUS_MODE_FIXED;
372
373 sceneModeList =
374 ExynosCamera::SCENE_MODE_AUTO
375 //| ExynosCamera::SCENE_MODE_ACTION
376 | ExynosCamera::SCENE_MODE_PORTRAIT
377 | ExynosCamera::SCENE_MODE_LANDSCAPE
378 | ExynosCamera::SCENE_MODE_NIGHT
379 //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT
380 //| ExynosCamera::SCENE_MODE_THEATRE
381 | ExynosCamera::SCENE_MODE_BEACH
382 | ExynosCamera::SCENE_MODE_SNOW
383 | ExynosCamera::SCENE_MODE_SUNSET
384 | ExynosCamera::SCENE_MODE_STEADYPHOTO
385 | ExynosCamera::SCENE_MODE_FIREWORKS
386 | ExynosCamera::SCENE_MODE_SPORTS
387 | ExynosCamera::SCENE_MODE_PARTY
388 | ExynosCamera::SCENE_MODE_CANDLELIGHT;
389 sceneMode = ExynosCamera::SCENE_MODE_AUTO;
390
391 whiteBalanceList =
392 ExynosCamera::WHITE_BALANCE_AUTO
393 | ExynosCamera::WHITE_BALANCE_INCANDESCENT
394 | ExynosCamera::WHITE_BALANCE_FLUORESCENT
395 //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT
396 | ExynosCamera::WHITE_BALANCE_DAYLIGHT
397 | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT
398 //| ExynosCamera::WHITE_BALANCE_TWILIGHT
399 //| ExynosCamera::WHITE_BALANCE_SHADE
400 ;
401 whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO;
402
403 autoWhiteBalanceLockSupported = true;
404 autoWhiteBalanceLock = false;
405
406 rotation = 0;
407 minExposure = -2;
408 maxExposure = 2;
409 exposure = 0;
410
411 autoExposureLockSupported = true;
412 autoExposureLock = false;
413
414 fps = 30;
415 focalLengthNum = 9;
416 focalLengthDen = 10;
417 supportVideoStabilization = false;
418 applyVideoStabilization = false;
419 videoStabilization = false;
420 maxNumMeteringAreas = 64;
421 maxNumDetectedFaces = 16;
422 maxNumFocusAreas = 0;
423 maxZoom = ZOOM_LEVEL_MAX;
424 hwZoomSupported = false;
425 zoom = 0;
426 gpsAltitude = 0;
427 gpsLatitude = 0;
428 gpsLongitude = 0;
429 gpsTimestamp = 0;
430}
431
432ExynosCameraInfoS5K4E5::ExynosCameraInfoS5K4E5()
433{
434 previewW = 1920;
435 previewH = 1080;
436 previewColorFormat = V4L2_PIX_FMT_YVU420M;
437 videoW = 1920;
438 videoH = 1080;
439 prefVideoPreviewW = 640;
440 prefVideoPreviewH = 360;
441 videoColorFormat = V4L2_PIX_FMT_NV12M;
442 pictureW = 2560;
443 pictureH = 1920;
444 pictureColorFormat = V4L2_PIX_FMT_YUYV;
445 thumbnailW = 320;
446 thumbnailH = 240;
447
448 antiBandingList =
449 ExynosCamera::ANTIBANDING_OFF
450 | ExynosCamera::ANTIBANDING_50HZ
451 | ExynosCamera::ANTIBANDING_60HZ
452 | ExynosCamera::ANTIBANDING_OFF;
453 antiBanding = ExynosCamera::ANTIBANDING_OFF;
454
455 effectList =
456 ExynosCamera::EFFECT_NONE
457 | ExynosCamera::EFFECT_MONO
458 | ExynosCamera::EFFECT_NEGATIVE
459 //| ExynosCamera::EFFECT_SOLARIZE
460 | ExynosCamera::EFFECT_SEPIA
461 //| ExynosCamera::EFFECT_POSTERIZE
462 //| ExynosCamera::EFFECT_WHITEBOARD
463 //| ExynosCamera::EFFECT_BLACKBOARD
464 //| ExynosCamera::EFFECT_AQUA
465 ;
466 effect = ExynosCamera::EFFECT_NONE;
467
468 flashModeList =
469 ExynosCamera::FLASH_MODE_OFF
470 | ExynosCamera::FLASH_MODE_AUTO
471 | ExynosCamera::FLASH_MODE_ON
472 //| ExynosCamera::FLASH_MODE_RED_EYE
473 | ExynosCamera::FLASH_MODE_TORCH;
474 flashMode = ExynosCamera::FLASH_MODE_OFF;
475
476 focusModeList =
477 ExynosCamera::FOCUS_MODE_AUTO
478 | ExynosCamera::FOCUS_MODE_INFINITY
479 | ExynosCamera::FOCUS_MODE_MACRO
480 //| ExynosCamera::FOCUS_MODE_FIXED
481 //| ExynosCamera::FOCUS_MODE_EDOF
482 | ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO
Dima Zavin88cc2302012-05-07 11:07:38 -0700483 // | ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE
Jiyoung Shin9426c422012-04-02 16:22:36 -0700484 | ExynosCamera::FOCUS_MODE_TOUCH
485 ;
486 focusMode = ExynosCamera::FOCUS_MODE_AUTO;
487
488 sceneModeList =
489 ExynosCamera::SCENE_MODE_AUTO
490 //| ExynosCamera::SCENE_MODE_ACTION
491 | ExynosCamera::SCENE_MODE_PORTRAIT
492 | ExynosCamera::SCENE_MODE_LANDSCAPE
493 | ExynosCamera::SCENE_MODE_NIGHT
494 //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT
495 //| ExynosCamera::SCENE_MODE_THEATRE
496 | ExynosCamera::SCENE_MODE_BEACH
497 | ExynosCamera::SCENE_MODE_SNOW
498 | ExynosCamera::SCENE_MODE_SUNSET
499 | ExynosCamera::SCENE_MODE_STEADYPHOTO
500 | ExynosCamera::SCENE_MODE_FIREWORKS
501 | ExynosCamera::SCENE_MODE_SPORTS
502 | ExynosCamera::SCENE_MODE_PARTY
503 | ExynosCamera::SCENE_MODE_CANDLELIGHT;
504 sceneMode = ExynosCamera::SCENE_MODE_AUTO;
505
506 whiteBalanceList =
507 ExynosCamera::WHITE_BALANCE_AUTO
508 | ExynosCamera::WHITE_BALANCE_INCANDESCENT
509 | ExynosCamera::WHITE_BALANCE_FLUORESCENT
510 //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT
511 | ExynosCamera::WHITE_BALANCE_DAYLIGHT
512 | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT
513 //| ExynosCamera::WHITE_BALANCE_TWILIGHT
514 //| ExynosCamera::WHITE_BALANCE_SHADE
515 ;
516 whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO;
517
518 autoWhiteBalanceLockSupported = true;
519 autoWhiteBalanceLock = false;
520
521 rotation = 0;
522 minExposure = -2;
523 maxExposure = 2;
524 exposure = 0;
525
526 autoExposureLockSupported = true;
527 autoExposureLock = false;
528
529 fps = 30;
530 focalLengthNum = 9;
531 focalLengthDen = 10;
532 supportVideoStabilization = true;
533 applyVideoStabilization = false;
534 videoStabilization = false;
535 maxNumMeteringAreas = 64;
536 maxNumDetectedFaces = 16;
537 maxNumFocusAreas = 2;
538 maxZoom = ZOOM_LEVEL_MAX;
539 hwZoomSupported = false;
540 zoom = 0;
541 gpsAltitude = 0;
542 gpsLatitude = 0;
543 gpsLongitude = 0;
544 gpsTimestamp = 0;
545}
546
547//////////////////////////////////////////////////
548
549#define PFX_NODE "/dev/video"
550
551#define M5MOLS_ENTITY_NAME "M5MOLS 5-001f"
552#define PFX_SUBDEV_ENTITY_MIPI_CSIS "s5p-mipi-csis"
553#define PFX_SUBDEV_ENTITY_FLITE "flite-subdev"
554#define PFX_SUBDEV_ENTITY_GSC_CAP "gsc-cap-subdev"
555#define PFX_VIDEODEV_ENTITY_FLITE "exynos-fimc-lite"
556#define PFX_VIDEODEV_ENTITY_GSC_CAP "exynos-gsc"
557
558#define MEDIA_DEV_INTERNAL_ISP "/dev/media2"
559#define MEDIA_DEV_EXTERNAL_ISP "/dev/media1"
560#define ISP_VD_NODE_OFFSET (40) //INTERNAL_ISP
561#define FLITE_VD_NODE_OFFSET (36) //External ISP
562
563#define VIDEO_NODE_PREVIEW_ID (3)
564#define VIDEO_NODE_RECODING_ID (2)
565#define VIDEO_NODE_SNAPSHOT_ID (1)
566
567#define ISP_SENSOR_MAX_ENTITIES 1
568#define ISP_SENSOR_PAD_SOURCE_FRONT 0
569#define ISP_SENSOR_PADS_NUM 1
570
571#define ISP_FRONT_MAX_ENTITIES 1
572#define ISP_FRONT_PAD_SINK 0
573#define ISP_FRONT_PAD_SOURCE_BACK 1
574#define ISP_FRONT_PAD_SOURCE_BAYER 2
575#define ISP_FRONT_PAD_SOURCE_SCALERC 3
576#define ISP_FRONT_PADS_NUM 4
577
578#define ISP_BACK_MAX_ENTITIES 1
579#define ISP_BACK_PAD_SINK 0
580#define ISP_BACK_PAD_SOURCE_3DNR 1
581#define ISP_BACK_PAD_SOURCE_SCALERP 2
582#define ISP_BACK_PADS_NUM 3
583
584#define ISP_MODULE_NAME "exynos5-fimc-is"
585#define ISP_SENSOR_ENTITY_NAME "exynos5-fimc-is-sensor"
586#define ISP_FRONT_ENTITY_NAME "exynos5-fimc-is-front"
587#define ISP_BACK_ENTITY_NAME "exynos5-fimc-is-back"
588#define ISP_VIDEO_BAYER_NAME "exynos5-fimc-is-bayer"
589#define ISP_VIDEO_SCALERC_NAME "exynos5-fimc-is-scalerc"
590#define ISP_VIDEO_3DNR_NAME "exynos5-fimc-is-3dnr"
591#define ISP_VIDEO_SCALERP_NAME "exynos5-fimc-is-scalerp"
592
593#define MIPI_NUM 1
594#define FLITE_NUM 1
595#define GSC_NUM 0
596
597#define PFX_SUBDEV_NODE "/dev/v4l-subdev"
598
599/*
600 * V 4 L 2 F I M C E X T E N S I O N S
601 *
602 */
603#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0)
604#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1)
605#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2)
606#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3)
607#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4)
608#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53)
609
610#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32)
611#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33)
612#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34)
613#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35)
614#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36)
615#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37)
616
617#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U')
618
619/* FOURCC for FIMC specific */
620#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y')
621#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6')
622#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1')
623#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2')
624
625///////////////////////////////////////////////////
626// Google Official API : Camera.Parameters
627// http://developer.android.com/reference/android/hardware/Camera.Parameters.html
628///////////////////////////////////////////////////
629
630ExynosCamera::ExynosCamera() :
631 m_flagCreate(false),
632 m_cameraId(CAMERA_ID_BACK),
633 m_defaultCameraInfo(NULL),
634 m_curCameraInfo(NULL),
635 m_jpegQuality(100),
636 m_jpegThumbnailQuality(100),
637 m_currentZoom(-1)
638{
639 memset(&m_sensorDev, 0, sizeof(struct devInfo));
640 memset(&m_mipiDev, 0, sizeof(struct devInfo));
641 memset(&m_fliteDev, 0, sizeof(struct devInfo));
642 memset(&m_gscPreviewDev, 0, sizeof(struct devInfo));
643 memset(&m_gscVideoDev, 0, sizeof(struct devInfo));
644 memset(&m_gscPictureDev, 0, sizeof(struct devInfo));
645
646 m_previewDev = NULL;
647 m_videoDev = NULL;
648 m_pictureDev = NULL;
649
650 m_tryPreviewStop = true;
651 m_tryVideoStop = true;
652 m_tryPictureStop = true;
653
654 m_flagStartFaceDetection = false;
655 m_flagAutoFocusRunning = false;
656
657 m_sensorEntity = NULL;
658 m_mipiEntity = NULL;
659 m_fliteSdEntity = NULL;
660 m_fliteVdEntity = NULL;
661 m_gscSdEntity = NULL;
662 m_gscVdEntity = NULL;
663 m_ispSensorEntity = NULL;
664 m_ispFrontEntity = NULL;
665 m_ispBackEntity = NULL;
666 m_ispScalercEntity = NULL;
667 m_ispScalerpEntity = NULL;
668 m_isp3dnrEntity = NULL;
669
670
671 for (int i = 0; i < VIDEO_MAX_FRAME; i++) {
672 m_validPreviewBuf[i] = false;
673 m_validVideoBuf [i] = false;
674 m_validPictureBuf[i] = false;
675 }
676
677 memset((void *)m_cameraName, 0, 32);
678
679 m_internalISP = true;
680 m_media = NULL;
681
682 memset(&mExifInfo, 0, sizeof(mExifInfo));
683}
684
685ExynosCamera::~ExynosCamera()
686{
687 if (m_flagCreate == true)
688 destroy();
689}
690
691bool ExynosCamera::create(int cameraId)
692{
693 int ret = 0;
694 unsigned int i;
695 int devNum;
696 char node[30];
697
698 struct media_link *links = NULL;
699
700 if (m_flagCreate == true) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700701 ALOGE("ERR(%s):Already created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700702 return false;
703 }
704
705 m_cameraId = cameraId;
706
707 ExynosBuffer nullBuf;
708
709 for (int i = 0; i < VIDEO_MAX_FRAME; i++) {
710 m_validPreviewBuf[i] = false;
711 m_validVideoBuf [i] = false;
712 m_validPictureBuf[i] = false;
713
714 m_previewBuf[i] = nullBuf;
715 m_videoBuf[i] = nullBuf;
716 m_pictureBuf[i] = nullBuf;
717 }
718
719 if (m_cameraId == CAMERA_ID_BACK)
720 m_internalISP = true;
721 // m_internalISP = false; // external ISP.
722 else
723 m_internalISP = true;
724
725 if (m_internalISP == true) {
726 //////////////////////////////
727 // internal ISP
728 //////////////////////////////
729 // media device open
730 m_media = exynos_media_open(MEDIA_DEV_INTERNAL_ISP);
731 if (m_media == NULL) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700732 ALOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -0700733 goto err;
734 }
735
736 //////////////////
737 // GET ENTITIES
738 //////////////////
739 // ISP sensor subdev
740 memset(&node, 0x00, sizeof(node));
741 strcpy(node, ISP_SENSOR_ENTITY_NAME);
742 m_ispSensorEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
743
744 // ISP front subdev
745 memset(&node, 0x00, sizeof(node));
746 strcpy(node, ISP_FRONT_ENTITY_NAME);
747 m_ispFrontEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
748
749 // ISP back subdev
750 memset(&node, 0x00, sizeof(node));
751 strcpy(node, ISP_BACK_ENTITY_NAME);
752 m_ispBackEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
753
754 // ISP ScalerC video node
755 memset(&node, 0x00, sizeof(node));
756 strcpy(node, ISP_VIDEO_SCALERC_NAME);
757 m_ispScalercEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
758
759 // ISP ScalerP video node
760 memset(&node, 0x00, sizeof(node));
761 strcpy(node, ISP_VIDEO_SCALERP_NAME);
762 m_ispScalerpEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
763
764 // ISP 3DNR video node
765 memset(&node, 0x00, sizeof(node));
766 strcpy(node, ISP_VIDEO_3DNR_NAME);
767 m_isp3dnrEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
768
Dima Zavinf4979f52012-05-01 21:49:24 -0700769 ALOGV("DEBUG(%s):m_ispSensorEntity : numlink : %d", __func__, m_ispSensorEntity->num_links);
770 ALOGV("DEBUG(%s):m_ispFrontEntity : numlink : %d", __func__, m_ispFrontEntity->num_links);
771 ALOGV("DEBUG(%s):m_ispBackEntity : numlink : %d", __func__, m_ispBackEntity->num_links);
772 ALOGV("DEBUG(%s):m_ispScalercEntity : numlink : %d", __func__, m_ispScalercEntity->num_links);
773 ALOGV("DEBUG(%s):m_ispScalerpEntity : numlink : %d", __func__, m_ispScalerpEntity->num_links);
774 ALOGV("DEBUG(%s):m_isp3dnrEntity : numlink : %d", __func__, m_isp3dnrEntity->num_links);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700775
776 //////////////////
777 // SETUP LINKS
778 //////////////////
779 // SENSOR TO FRONT
780 links = m_ispSensorEntity->links;
781 if (links == NULL ||
782 links->source->entity != m_ispSensorEntity ||
783 links->sink->entity != m_ispFrontEntity) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700784 ALOGE("ERR(%s):Can not make link isp_sensor to isp_front", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700785 goto err;
786 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700787 ALOGE("ERR(%s):Can not make setup isp_sensor to isp_front", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700788 goto err;
789 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700790 ALOGV("DEBUG(%s):[LINK SUCCESS] Sensor to front", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700791
792 // FRONT TO BACK
793 for (i = 0; i < m_ispFrontEntity->num_links; i++) {
794 links = &m_ispFrontEntity->links[i];
795 if (links == NULL ||
796 links->source->entity != m_ispFrontEntity ||
797 links->sink->entity != m_ispBackEntity) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700798 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_ispFrontEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700799 links->source->entity, m_ispFrontEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700800 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_ispBackEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700801 links->sink->entity, m_ispBackEntity);
802 continue;
803 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700804 ALOGE("ERR(%s):Can not make setup isp_front to isp_back", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700805 goto err;
806 }
807 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700808 ALOGV("DEBUG(%s):[LINK SUCCESS] front to back", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700809
810 // BACK TO ScalerP Video
811 for (i = 0; i < m_ispBackEntity->num_links; i++) {
812 links = &m_ispBackEntity->links[i];
813 if (links == NULL ||
814 links->source->entity != m_ispBackEntity ||
815 links->sink->entity != m_ispScalerpEntity) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700816 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_ispBackEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700817 links->source->entity, m_ispBackEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700818 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_ispScalerpEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700819 links->sink->entity, m_ispScalerpEntity);
820 continue;
821 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700822 ALOGE("ERR(%s):Can not make setup isp_back to scalerP", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700823 goto err;
824 }
825 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700826 ALOGV("DEBUG(%s):[LINK SUCCESS] back to scalerP", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700827
828 sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_PREVIEW_ID));
829 m_gscPreviewDev.fd = exynos_v4l2_open(node, O_RDWR, 0);
830 if (m_gscPreviewDev.fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700831 ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -0700832 goto err;
833 }
834 m_previewDev = &m_gscPreviewDev;
835
836 sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_RECODING_ID));
837 m_gscVideoDev.fd = exynos_v4l2_open(node, O_RDWR, 0);
838 if (m_gscVideoDev.fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700839 ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -0700840 goto err;
841 }
842 m_videoDev = &m_gscVideoDev;
843
844 sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_SNAPSHOT_ID));
845 m_gscPictureDev.fd = exynos_v4l2_open(node, O_RDWR, 0);
846 if (m_gscPictureDev.fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700847 ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -0700848 goto err;
849 }
850 m_pictureDev = &m_gscPictureDev;
851
852 } else {
853 //////////////////////////////
854 // external ISP
855 //////////////////////////////
856 // media device open
857 m_media = exynos_media_open(MEDIA_DEV_EXTERNAL_ISP);
858 if (m_media == NULL) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700859 ALOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -0700860 goto err;
861 }
862
863 //////////////////
864 // GET ENTITIES
865 //////////////////
866 // camera subdev
867 strcpy(node, M5MOLS_ENTITY_NAME);
Dima Zavinf4979f52012-05-01 21:49:24 -0700868 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700869 m_sensorEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700870 ALOGV("DEBUG(%s):m_sensorEntity : 0x%p", __func__, m_sensorEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700871
872 // mipi subdev
873 sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_MIPI_CSIS, MIPI_NUM);
Dima Zavinf4979f52012-05-01 21:49:24 -0700874 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700875 m_mipiEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700876 ALOGV("DEBUG(%s):m_mipiEntity : 0x%p", __func__, m_mipiEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700877
878 // fimc-lite subdev
879 sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_FLITE, FLITE_NUM);
Dima Zavinf4979f52012-05-01 21:49:24 -0700880 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700881 m_fliteSdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700882 ALOGV("DEBUG(%s):m_fliteSdEntity : 0x%p", __func__, m_fliteSdEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700883
884 // fimc-lite videodev
885 sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_FLITE, FLITE_NUM);
Dima Zavinf4979f52012-05-01 21:49:24 -0700886 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700887 m_fliteVdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700888 ALOGV("DEBUG(%s):m_fliteVdEntity : 0x%p", __func__, m_fliteVdEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700889
890 // gscaler subdev
891 sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_GSC_CAP, GSC_NUM);
Dima Zavinf4979f52012-05-01 21:49:24 -0700892 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700893 m_gscSdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700894 ALOGV("DEBUG(%s):m_gscSdEntity : 0x%p", __func__, m_gscSdEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700895
896 // gscaler videodev
897 sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_GSC_CAP, GSC_NUM);
Dima Zavinf4979f52012-05-01 21:49:24 -0700898 ALOGV("DEBUG(%s):node : %s", __func__, node);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700899 m_gscVdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node));
Dima Zavinf4979f52012-05-01 21:49:24 -0700900 ALOGV("DEBUG(%s):m_gscVdEntity : 0x%p", __func__, m_gscVdEntity);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700901
Dima Zavinf4979f52012-05-01 21:49:24 -0700902 ALOGV("DEBUG(%s):sensor_sd : numlink : %d", __func__, m_sensorEntity->num_links);
903 ALOGV("DEBUG(%s):mipi_sd : numlink : %d", __func__, m_mipiEntity->num_links);
904 ALOGV("DEBUG(%s):flite_sd : numlink : %d", __func__, m_fliteSdEntity->num_links);
905 ALOGV("DEBUG(%s):flite_vd : numlink : %d", __func__, m_fliteVdEntity->num_links);
906 ALOGV("DEBUG(%s):gsc_sd : numlink : %d", __func__, m_gscSdEntity->num_links);
907 ALOGV("DEBUG(%s):gsc_vd : numlink : %d", __func__, m_gscVdEntity->num_links);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700908
909 //////////////////
910 // SETUP LINKS
911 //////////////////
912 // sensor subdev to mipi subdev
913 links = m_sensorEntity->links;
914 if (links == NULL ||
915 links->source->entity != m_sensorEntity ||
916 links->sink->entity != m_mipiEntity) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700917 ALOGE("ERR(%s):Cannot make link camera sensor to mipi", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700918 goto err;
919 }
920
921 if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700922 ALOGE("ERR(%s):Cannot make setup camera sensor to mipi", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700923 goto err;
924 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700925 ALOGV("DEBUG(%s):[LINK SUCCESS] sensor subdev to mipi subdev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700926
927 // mipi subdev to fimc-lite subdev
928 for (i = 0; i < m_mipiEntity->num_links; i++) {
929 links = &m_mipiEntity->links[i];
Dima Zavinf4979f52012-05-01 21:49:24 -0700930 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_mipiEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700931 links->source->entity, m_mipiEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700932 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_fliteSdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700933 links->sink->entity, m_fliteSdEntity);
934 if (links == NULL ||
935 links->source->entity != m_mipiEntity ||
936 links->sink->entity != m_fliteSdEntity) {
937 continue;
938 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700939 ALOGE("ERR(%s):Cannot make setup mipi subdev to fimc-lite subdev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700940 goto err;
941 }
942 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700943 ALOGV("DEBUG(%s):[LINK SUCCESS] mipi subdev to fimc-lite subdev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700944
945 // fimc-lite subdev TO fimc-lite video dev
946 for (i = 0; i < m_fliteSdEntity->num_links; i++) {
947 links = &m_fliteSdEntity->links[i];
Dima Zavinf4979f52012-05-01 21:49:24 -0700948 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_fliteSdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700949 links->source->entity, m_fliteSdEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700950 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_fliteVdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700951 links->sink->entity, m_fliteVdEntity);
952 if (links == NULL ||
953 links->source->entity != m_fliteSdEntity ||
954 links->sink->entity != m_fliteVdEntity) {
955 continue;
956 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700957 ALOGE("ERR(%s):Cannot make setup fimc-lite subdev to fimc-lite video dev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700958 goto err;
959 }
960 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700961 ALOGV("DEBUG(%s):[LINK SUCCESS] fimc-lite subdev to fimc-lite video dev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700962
963 // fimc-lite subdev to gscaler subdev
964 for (i = 0; i < m_gscSdEntity->num_links; i++) {
965 links = &m_gscSdEntity->links[i];
Dima Zavinf4979f52012-05-01 21:49:24 -0700966 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_fliteSdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700967 links->source->entity, m_fliteSdEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700968 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_gscSdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700969 links->sink->entity, m_gscSdEntity);
970 if (links == NULL ||
971 links->source->entity != m_fliteSdEntity ||
972 links->sink->entity != m_gscSdEntity) {
973 continue;
974 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700975 ALOGE("ERR(%s):Cannot make setup fimc-lite subdev to gscaler subdev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700976 goto err;
977 }
978 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700979 ALOGV("DEBUG(%s):[LINK SUCCESS] fimc-lite subdev to gscaler subdev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700980
981 // gscaler subdev to gscaler video dev
982 for (i = 0; i < m_gscVdEntity->num_links; i++) {
983 links = &m_gscVdEntity->links[i];
Dima Zavinf4979f52012-05-01 21:49:24 -0700984 ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_gscSdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700985 links->source->entity, m_gscSdEntity);
Dima Zavinf4979f52012-05-01 21:49:24 -0700986 ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_gscVdEntity : %p", __func__, i,
Jiyoung Shin9426c422012-04-02 16:22:36 -0700987 links->sink->entity, m_gscVdEntity);
988 if (links == NULL ||
989 links->source->entity != m_gscSdEntity ||
990 links->sink->entity != m_gscVdEntity) {
991 continue;
992 } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -0700993 ALOGE("ERR(%s):Cannot make setup gscaler subdev to gscaler video dev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700994 goto err;
995 }
996 }
Dima Zavinf4979f52012-05-01 21:49:24 -0700997 ALOGV("DEBUG(%s):[LINK SUCCESS] gscaler subdev to gscaler video dev", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -0700998
999 sprintf(node, "%s%d", PFX_NODE, (FLITE_VD_NODE_OFFSET + VIDEO_NODE_PREVIEW_ID));
1000 m_fliteDev.fd = exynos_v4l2_open(node, O_RDWR, 0);
1001 if (m_fliteDev.fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001002 ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno));
Jiyoung Shin9426c422012-04-02 16:22:36 -07001003 goto err;
1004 }
1005 m_previewDev = &m_fliteDev;
1006 m_videoDev = &m_fliteDev;
1007 m_pictureDev = &m_fliteDev;
1008 }
1009
1010 m_previewDev->flagStart = false;
1011 m_videoDev->flagStart = false;
1012 m_pictureDev->flagStart = false;
1013
1014 m_tryPreviewStop = true;
1015 m_tryVideoStop = true;
1016 m_tryPictureStop = true;
1017
1018 m_flagStartFaceDetection = false;
1019 m_flagAutoFocusRunning = false;
1020
1021 if (exynos_v4l2_enuminput(m_previewDev->fd, m_cameraId, m_cameraName) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001022 ALOGE("ERR(%s):exynos_v4l2_enuminput(%d, %s) fail", __func__, m_cameraId, m_cameraName);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001023 goto err;
1024 }
1025
1026 // HACK
1027 if (m_cameraId == CAMERA_ID_BACK)
1028 strcpy(m_cameraName, "S5K4E5");
1029 else
1030 strcpy(m_cameraName, "S5K6A3");
1031
1032 if (exynos_v4l2_s_input(m_previewDev->fd, m_cameraId) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001033 ALOGE("ERR(%s):exynos_v4l2_s_input() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001034 goto err;
1035 }
1036
1037 if (strcmp((const char*)m_cameraName, "S5K4E5") == 0) {
1038 m_defaultCameraInfo = new ExynosCameraInfoS5K4E5;
1039 m_curCameraInfo = new ExynosCameraInfoS5K4E5;
1040 } else if (strcmp((const char*)m_cameraName, "S5K6A3") == 0) {
1041 m_defaultCameraInfo = new ExynosCameraInfoS5K6A3;
1042 m_curCameraInfo = new ExynosCameraInfoS5K6A3;
1043 } else if (strcmp((const char*)m_cameraName, "M5M0") == 0) {
1044 m_defaultCameraInfo = new ExynosCameraInfoM5M0;
1045 m_curCameraInfo = new ExynosCameraInfoM5M0;
1046 } else {
Dima Zavinf4979f52012-05-01 21:49:24 -07001047 ALOGE("ERR(%s):invalid camera Name (%s) fail", __func__, m_cameraName);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001048 goto err;
1049 }
1050
1051 m_setExifFixedAttribute();
1052
1053 m_flagCreate = true;
1054 return true;
1055
1056err:
1057 if (m_defaultCameraInfo)
1058 delete m_defaultCameraInfo;
1059 m_defaultCameraInfo = NULL;
1060
1061 if (m_curCameraInfo)
1062 delete m_curCameraInfo;
1063 m_curCameraInfo = NULL;
1064
1065 if (0 < m_videoDev->fd)
1066 exynos_v4l2_close(m_videoDev->fd);
1067 m_videoDev->fd = 0;
1068
1069 if (0 < m_pictureDev->fd)
1070 exynos_v4l2_close(m_pictureDev->fd);
1071 m_pictureDev->fd = 0;
1072
1073 if (0 < m_previewDev->fd)
1074 exynos_v4l2_close(m_previewDev->fd);
1075 m_previewDev->fd = 0;
1076
1077 if (m_media)
1078 exynos_media_close(m_media);
1079 m_media = NULL;
1080
1081 return false;
1082}
1083
1084bool ExynosCamera::destroy(void)
1085{
1086 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001087 ALOGE("ERR(%s):Not yet created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001088 return false;
1089 }
1090
1091 if (m_pictureDev->flagStart == true)
1092 stopPicture();
1093
1094 if (m_videoDev->flagStart == true)
1095 stopVideo();
1096
1097 if (m_previewDev->flagStart == true)
1098 stopPreview();
1099
1100 if (m_defaultCameraInfo)
1101 delete m_defaultCameraInfo;
1102 m_defaultCameraInfo = NULL;
1103
1104 if (m_curCameraInfo)
1105 delete m_curCameraInfo;
1106 m_curCameraInfo = NULL;
1107
1108 // close m_previewDev->fd after stopVideo() because stopVideo()
1109 // uses m_previewDev->fd to change frame rate
1110 if (0 < m_videoDev->fd)
1111 exynos_v4l2_close(m_videoDev->fd);
1112 m_videoDev->fd = 0;
1113
1114 if (0 < m_pictureDev->fd)
1115 exynos_v4l2_close(m_pictureDev->fd);
1116 m_pictureDev->fd = 0;
1117
1118 if (0 < m_previewDev->fd)
1119 exynos_v4l2_close(m_previewDev->fd);
1120 m_previewDev->fd = 0;
1121
1122 if (m_media)
1123 exynos_media_close(m_media);
1124 m_media = NULL;
1125
1126 m_flagCreate = false;
1127
1128 return true;
1129}
1130
1131bool ExynosCamera::flagCreate(void)
1132{
1133 return m_flagCreate;
1134}
1135
1136int ExynosCamera::getCameraId(void)
1137{
1138 return m_cameraId;
1139}
1140
1141char *ExynosCamera::getCameraName(void)
1142{
1143 return m_cameraName;
1144}
1145
1146int ExynosCamera::getPreviewFd(void)
1147{
1148 return m_previewDev->fd;
1149}
1150
1151int ExynosCamera::getPictureFd(void)
1152{
1153 return m_pictureDev->fd;
1154}
1155
1156int ExynosCamera::getVideoFd(void)
1157{
1158 return m_videoDev->fd;
1159}
1160
1161bool ExynosCamera::startPreview(void)
1162{
1163 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001164 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001165 return false;
1166 }
1167
1168 if (m_previewDev->flagStart == false) {
1169 if (m_setWidthHeight(PREVIEW_MODE,
1170 m_previewDev->fd,
1171 &m_previewDev->events,
1172 m_curCameraInfo->previewW,
1173 m_curCameraInfo->previewH,
1174 m_curCameraInfo->previewColorFormat,
1175 m_previewBuf,
1176 m_validPreviewBuf) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001177 ALOGE("ERR(%s):m_setWidthHeight() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001178 return false;
1179 }
1180
1181 if (setPreviewFrameRate(m_curCameraInfo->fps) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001182 ALOGE("ERR(%s):Fail toggle setPreviewFrameRate(%d)",
Jiyoung Shin9426c422012-04-02 16:22:36 -07001183 __func__, m_curCameraInfo->fps);
1184
1185 if (exynos_v4l2_streamon(m_previewDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001186 ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001187 return false;
1188 }
1189
1190 if (m_curCameraInfo->focusMode == FOCUS_MODE_CONTINUOUS_VIDEO
1191 || m_curCameraInfo->focusMode == FOCUS_MODE_CONTINUOUS_PICTURE) {
1192 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_CAF_START_STOP, CAF_START) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001193 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001194 return false;
1195 }
1196 }
1197
1198 m_tryPreviewStop = false;
1199 m_previewDev->flagStart = true;
1200
1201/* TODO */
1202/* DIS is only supported BACK camera(4E5) currently. */
1203#ifdef USE_DIS
1204 bool toggle = getVideoStabilization();
1205
1206 if (setVideoStabilization(toggle) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001207 ALOGE("ERR(%s):setVideoStabilization() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001208#endif
1209
1210#ifdef USE_3DNR
1211 if (m_recordingHint == true && getCameraId() == CAMERA_ID_BACK) {
1212 if (set3DNR(true) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001213 ALOGE("ERR(%s):set3DNR() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001214 }
1215#endif
1216
1217#ifdef USE_ODC
1218 if (setODC(true) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001219 ALOGE("ERR(%s):setODC() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001220#endif
1221 }
1222
1223 return true;
1224}
1225
1226bool ExynosCamera::stopPreview(void)
1227{
1228 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001229 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001230 return false;
1231 }
1232
1233 if (m_previewDev->flagStart == true) {
1234
1235 if (m_curCameraInfo->flashMode == FLASH_MODE_TORCH)
1236 setFlashMode(FLASH_MODE_OFF);
1237
1238 m_tryPreviewStop = true;
1239
1240 // skip stopPreview
1241 if ( (m_previewDev == m_videoDev && m_tryVideoStop == false)
1242 || (m_previewDev == m_pictureDev && m_tryPictureStop == false))
1243 return true;
1244
1245/* TODO */
1246/* Can not use 3DNR, ODC and DIS function because HW problem at exynos5250 EVT0 */
1247#ifdef USE_3DNR
1248 if (set3DNR(false) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001249 ALOGE("ERR(%s):set3DNR() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001250#endif
1251
1252#ifdef USE_ODC
1253 if (setODC(false) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07001254 ALOGE("ERR(%s):setODC() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001255#endif
1256
1257 if (exynos_v4l2_streamoff(m_previewDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001258 ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001259 return false;
1260 }
1261
1262 struct v4l2_requestbuffers req;
1263 req.count = 0;
1264 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001265 req.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001266
1267 if (exynos_v4l2_reqbufs(m_previewDev->fd, &req) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001268 ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001269 return false;
1270 }
1271
1272 m_previewDev->flagStart = false;
1273
1274 m_flagStartFaceDetection = false;
1275 }
1276
1277 return true;
1278}
1279
1280bool ExynosCamera::flagStartPreview(void)
1281{
1282 return m_previewDev->flagStart;
1283}
1284
1285int ExynosCamera::getPreviewMaxBuf(void)
1286{
1287 return VIDEO_MAX_FRAME;
1288}
1289
1290bool ExynosCamera::setPreviewBuf(ExynosBuffer *buf)
1291{
1292 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001293 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001294 return false;
1295 }
1296
1297 if (VIDEO_MAX_FRAME <= buf->reserved.p) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001298 ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001299 return false;
1300 }
1301
1302 m_previewBuf[buf->reserved.p] = *buf;
1303
1304 // HACK : Driver not yet support cb,cr of YV12
1305 m_previewBuf[buf->reserved.p].virt.extP[1] = buf->virt.extP[2];
1306 m_previewBuf[buf->reserved.p].virt.extP[2] = buf->virt.extP[1];
1307
1308 return true;
1309}
1310
1311bool ExynosCamera::getPreviewBuf(ExynosBuffer *buf)
1312{
1313 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001314 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001315 return false;
1316 }
1317
1318 if (m_previewDev->flagStart == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001319 ALOGE("ERR(%s):Not yet preview started fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001320 return false;
1321 }
1322
1323 struct v4l2_buffer v4l2_buf;
1324 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1325
1326 v4l2_buf.m.planes = planes;
1327 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001328 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001329 v4l2_buf.length = 0;
1330
1331 for (int i = 0; i < 3; i++) {
1332 if (m_previewBuf[0].size.extS[i] != 0)
1333 v4l2_buf.length++;
1334 }
1335
1336 if (exynos_v4l2_dqbuf(m_previewDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001337 ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001338 return false;
1339 }
1340
1341 if (VIDEO_MAX_FRAME <= v4l2_buf.index) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001342 ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001343 return false;
1344 }
1345
1346 *buf = m_previewBuf[v4l2_buf.index];
1347
1348 return true;
1349}
1350
1351bool ExynosCamera::putPreviewBuf(ExynosBuffer *buf)
1352{
1353 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001354 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001355 return false;
1356 }
1357
1358 if (m_validPreviewBuf[buf->reserved.p] == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001359 ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001360 return false;
1361 }
1362
1363 struct v4l2_buffer v4l2_buf;
1364 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1365
1366 v4l2_buf.m.planes = planes;
1367 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001368 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001369 v4l2_buf.index = buf->reserved.p;
1370 v4l2_buf.length = 0;
1371
1372 for (int i = 0; i < 3; i++) {
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001373 v4l2_buf.m.planes[i].m.fd= m_previewBuf[buf->reserved.p].fd.extFd[i];
Jiyoung Shin9426c422012-04-02 16:22:36 -07001374 v4l2_buf.m.planes[i].length = m_previewBuf[buf->reserved.p].size.extS[i];
1375
1376 if (m_previewBuf[buf->reserved.p].size.extS[i] != 0)
1377 v4l2_buf.length++;
1378 }
1379
1380 if (exynos_v4l2_qbuf(m_previewDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001381 ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001382 return false;
1383 }
1384
1385 return true;
1386}
1387
1388bool ExynosCamera::setVideoSize(int w, int h)
1389{
1390 m_curCameraInfo->videoW = w;
1391 m_curCameraInfo->videoH = h;
1392
1393#ifdef USE_3DNR_DMAOUT
1394 // HACK : Video 3dnr port support resize. So, we must make max size video w, h
1395 m_curCameraInfo->videoW = m_defaultCameraInfo->videoW;
1396 m_curCameraInfo->videoH = m_defaultCameraInfo->videoH;
1397#endif
1398 return true;
1399}
1400
1401bool ExynosCamera::getVideoSize(int *w, int *h)
1402{
1403 *w = m_curCameraInfo->videoW;
1404 *h = m_curCameraInfo->videoH;
1405 return true;
1406}
1407
1408bool ExynosCamera::setVideoFormat(int colorFormat)
1409{
1410 m_curCameraInfo->videoColorFormat = colorFormat;
1411 return true;
1412}
1413
1414int ExynosCamera::getVideoFormat(void)
1415{
1416 return m_curCameraInfo->videoColorFormat;
1417}
1418
1419bool ExynosCamera::startVideo(void)
1420{
1421 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001422 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001423 return false;
1424 }
1425
1426#ifdef USE_3DNR_DMAOUT
1427 if (m_videoDev->flagStart == false) {
1428 if (m_setWidthHeight(VIDEO_MODE,
1429 m_videoDev->fd,
1430 &m_videoDev->events,
1431 m_curCameraInfo->videoW,
1432 m_curCameraInfo->videoH,
1433 m_curCameraInfo->videoColorFormat,
1434 m_videoBuf,
1435 m_validVideoBuf) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001436 ALOGE("ERR(%s):m_setWidthHeight() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001437 return false;
1438 }
1439
1440 if (exynos_v4l2_streamon(m_videoDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001441 ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001442 return false;
1443 }
1444
1445 m_tryVideoStop = false;
1446 m_videoDev->flagStart = true;
1447 }
1448#endif
1449
1450 return true;
1451}
1452
1453bool ExynosCamera::stopVideo(void)
1454{
1455 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001456 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001457 return false;
1458 }
1459
1460 if (m_videoDev->flagStart == true) {
1461
1462 m_tryVideoStop = true;
1463
1464 // skip stopVideo
1465 if ( (m_videoDev == m_previewDev && m_tryPreviewStop == false)
1466 || (m_videoDev == m_pictureDev && m_tryPictureStop == false))
1467 return true;
1468
1469 if (exynos_v4l2_streamoff(m_videoDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001470 ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001471 return false;
1472 }
1473 struct v4l2_requestbuffers req;
1474 req.count = 0;
1475 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001476 req.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001477
1478 if (exynos_v4l2_reqbufs(m_videoDev->fd, &req) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001479 ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001480 return false;
1481 }
1482
1483 m_videoDev->flagStart = false;
1484 }
1485
1486 return true;
1487}
1488
1489bool ExynosCamera::flagStartVideo(void)
1490{
1491 return m_videoDev->flagStart;
1492}
1493
1494int ExynosCamera::getVideoMaxBuf(void)
1495{
1496 return VIDEO_MAX_FRAME;
1497}
1498
1499bool ExynosCamera::setVideoBuf(ExynosBuffer *buf)
1500{
1501 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001502 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001503 return false;
1504 }
1505
1506 if (VIDEO_MAX_FRAME <= buf->reserved.p) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001507 ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001508 return false;
1509 }
1510
1511 m_videoBuf[buf->reserved.p] = *buf;
1512 return true;
1513}
1514
1515bool ExynosCamera::getVideoBuf(ExynosBuffer *buf)
1516{
1517 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001518 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001519 return false;
1520 }
1521
1522 if (m_videoDev->flagStart == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001523 ALOGE("ERR(%s):Not yet video started fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001524 return false;
1525 }
1526
1527 struct v4l2_buffer v4l2_buf;
1528 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1529
1530 v4l2_buf.m.planes = planes;
1531 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001532 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001533 v4l2_buf.length = 0;
1534
1535 for (int i = 0; i < 3; i++) {
1536 if (m_videoBuf[0].size.extS[i] != 0)
1537 v4l2_buf.length++;
1538 }
1539
1540 if (exynos_v4l2_dqbuf(m_videoDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001541 ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001542 return false;
1543 }
1544
1545 if (VIDEO_MAX_FRAME <= v4l2_buf.index) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001546 ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001547 return false;
1548 }
1549
1550 *buf = m_videoBuf[v4l2_buf.index];
1551
1552 return true;
1553}
1554
1555bool ExynosCamera::putVideoBuf(ExynosBuffer *buf)
1556{
1557 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001558 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001559 return false;
1560 }
1561
1562 if (m_videoDev->flagStart == false) {
1563 /* this can happen when recording frames are returned after
1564 * the recording is stopped at the driver level. we don't
1565 * need to return the buffers in this case and we've seen
1566 * cases where fimc could crash if we called qbuf and it
1567 * wasn't expecting it.
1568 */
Dima Zavinf4979f52012-05-01 21:49:24 -07001569 ALOGV("DEBUG(%s):recording not in progress, ignoring", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001570 return true;
1571 }
1572
1573 if (m_validVideoBuf[buf->reserved.p] == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001574 ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001575 return false;
1576 }
1577
1578 struct v4l2_buffer v4l2_buf;
1579 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1580
1581 v4l2_buf.m.planes = planes;
1582 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001583 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001584 v4l2_buf.index = buf->reserved.p;
1585 v4l2_buf.length = 0;
1586
1587 for (int i = 0; i < 3; i++) {
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001588 v4l2_buf.m.planes[i].m.fd = (unsigned long)m_videoBuf[buf->reserved.p].fd.extFd[i];
Jiyoung Shin9426c422012-04-02 16:22:36 -07001589 v4l2_buf.m.planes[i].length = m_videoBuf[buf->reserved.p].size.extS[i];
1590
1591 if (m_videoBuf[buf->reserved.p].size.extS[i] != 0)
1592 v4l2_buf.length++;
1593 }
1594
1595 if (exynos_v4l2_qbuf(m_videoDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001596 ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001597 return false;
1598 }
1599
1600 return true;
1601}
1602
1603bool ExynosCamera::startPicture(void)
1604{
1605 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001606 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001607 return false;
1608 }
1609
1610 if (m_pictureDev->flagStart == false) {
1611 if (m_setWidthHeight(PICTURE_MODE,
1612 m_pictureDev->fd,
1613 &m_pictureDev->events,
1614 m_curCameraInfo->pictureW,
1615 m_curCameraInfo->pictureH,
1616 m_curCameraInfo->pictureColorFormat,
1617 m_pictureBuf,
1618 m_validPictureBuf) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001619 ALOGE("ERR(%s):m_setWidthHeight() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001620 return false;
1621 }
1622
1623 if (exynos_v4l2_streamon(m_pictureDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001624 ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001625 return false;
1626 }
1627
1628 m_tryPictureStop = false;
1629 m_pictureDev->flagStart = true;
1630 }
1631
1632 return true;
1633}
1634
1635bool ExynosCamera::stopPicture(void)
1636{
1637 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001638 ALOGE("ERR(%s):Not yet Created", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001639 return false;
1640 }
1641
1642 if (m_pictureDev->flagStart == true) {
1643
1644 m_tryPictureStop = true;
1645
1646 // skip stopPicture
1647 if ( (m_pictureDev == m_previewDev && m_tryPreviewStop == false)
1648 || (m_pictureDev == m_videoDev && m_tryVideoStop == false))
1649 return true;
1650
1651 if (exynos_v4l2_streamoff(m_pictureDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001652 ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001653 return false;
1654 }
1655
1656 struct v4l2_requestbuffers req;
1657 req.count = 0;
1658 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001659 req.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001660
1661 if (exynos_v4l2_reqbufs(m_pictureDev->fd, &req) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001662 ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001663 return false;
1664 }
1665
1666 m_pictureDev->flagStart = false;
1667 }
1668
1669 return true;
1670}
1671
1672bool ExynosCamera::flagStartPicture(void)
1673{
1674 return m_pictureDev->flagStart;
1675}
1676
1677int ExynosCamera::getPictureMaxBuf(void)
1678{
1679 return VIDEO_MAX_FRAME;
1680}
1681
1682bool ExynosCamera::setPictureBuf(ExynosBuffer *buf)
1683{
1684 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001685 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001686 return false;
1687 }
1688
1689 if (VIDEO_MAX_FRAME <= buf->reserved.p) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001690 ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001691 return false;
1692 }
1693
1694 m_pictureBuf[buf->reserved.p] = *buf;
1695 return true;
1696}
1697
1698bool ExynosCamera::getPictureBuf(ExynosBuffer *buf)
1699{
1700 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001701 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001702 return false;
1703 }
1704
1705 if (m_pictureDev->flagStart == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001706 ALOGE("ERR(%s):Not yet picture started fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001707 return false;
1708 }
1709
1710 struct v4l2_buffer v4l2_buf;
1711 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1712
1713 v4l2_buf.m.planes = planes;
1714 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001715 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001716 v4l2_buf.length = 0;
1717
1718 for (int i = 0; i < 3; i++) {
1719 if (m_pictureBuf[0].size.extS[i] != 0)
1720 v4l2_buf.length++;
1721 }
1722
1723 if (exynos_v4l2_dqbuf(m_pictureDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001724 ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001725 return false;
1726 }
1727
1728 if (VIDEO_MAX_FRAME <= v4l2_buf.index) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001729 ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001730 return false;
1731 }
1732
1733 *buf = m_pictureBuf[v4l2_buf.index];
1734
1735 return true;
1736}
1737
1738bool ExynosCamera::putPictureBuf(ExynosBuffer *buf)
1739{
1740 if (m_flagCreate == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001741 ALOGE("ERR(%s):Not yet created fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001742 return false;
1743 }
1744
1745 if (m_pictureDev->flagStart == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001746 ALOGE("ERR(%s):Not yet picture started fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001747 return false;
1748 }
1749
1750 if (m_validPictureBuf[buf->reserved.p] == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001751 ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001752 return false;
1753 }
1754
1755 struct v4l2_buffer v4l2_buf;
1756 struct v4l2_plane planes[VIDEO_MAX_PLANES];
1757
1758 v4l2_buf.m.planes = planes;
1759 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001760 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07001761 v4l2_buf.index = buf->reserved.p;
1762 v4l2_buf.length = 0;
1763
1764 for (int i = 0; i < 3; i++) {
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07001765 v4l2_buf.m.planes[i].m.fd = (unsigned long)m_pictureBuf[buf->reserved.p].fd.extFd[i];
Jiyoung Shin9426c422012-04-02 16:22:36 -07001766 v4l2_buf.m.planes[i].length = m_pictureBuf[buf->reserved.p].size.extS[i];
1767
1768 if (m_pictureBuf[buf->reserved.p].size.extS[i] != 0)
1769 v4l2_buf.length++;
1770 }
1771
1772 if (exynos_v4l2_qbuf(m_pictureDev->fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001773 ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001774 return false;
1775 }
1776
1777 return true;
1778}
1779
1780bool ExynosCamera::yuv2Jpeg(ExynosBuffer *yuvBuf,
1781 ExynosBuffer *jpegBuf,
1782 ExynosRect *rect)
1783{
1784 unsigned char *addr;
1785
1786 ExynosJpegEncoderForCamera jpegEnc;
1787 bool ret = false;
1788
1789 unsigned int *yuvSize = yuvBuf->size.extS;
1790
1791 if (jpegEnc.create()) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001792 ALOGE("ERR(%s):jpegEnc.create() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001793 goto jpeg_encode_done;
1794 }
1795
1796 if (jpegEnc.setQuality(m_jpegQuality)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001797 ALOGE("ERR(%s):jpegEnc.setQuality() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001798 goto jpeg_encode_done;
1799 }
1800
1801 if (jpegEnc.setSize(rect->w, rect->h)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001802 ALOGE("ERR(%s):jpegEnc.setSize() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001803 goto jpeg_encode_done;
1804 }
1805
1806 if (jpegEnc.setColorFormat(rect->colorFormat)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001807 ALOGE("ERR(%s):jpegEnc.setColorFormat() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001808 goto jpeg_encode_done;
1809 }
1810
1811 if (jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001812 ALOGE("ERR(%s):jpegEnc.setJpegFormat() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001813 goto jpeg_encode_done;
1814 }
1815
1816 if (m_curCameraInfo->thumbnailW != 0 && m_curCameraInfo->thumbnailH != 0) {
1817 mExifInfo.enableThumb = true;
1818 if (jpegEnc.setThumbnailSize(m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001819 ALOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __func__, m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001820 goto jpeg_encode_done;
1821 }
1822
1823 if (0 < m_jpegThumbnailQuality && m_jpegThumbnailQuality <= 100) {
1824 if (jpegEnc.setThumbnailQuality(m_jpegThumbnailQuality)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001825 ALOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __func__, m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001826 goto jpeg_encode_done;
1827 }
1828 }
1829
1830 m_setExifChangedAttribute(&mExifInfo, rect);
1831 } else {
1832 mExifInfo.enableThumb = false;
1833 }
1834
1835 if (jpegEnc.setInBuf((char **)&(yuvBuf->virt.p), (int *)yuvSize)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001836 ALOGE("ERR(%s):jpegEnc.setInBuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001837 goto jpeg_encode_done;
1838 }
1839
1840 if (jpegEnc.setOutBuf(jpegBuf->virt.p, jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2])) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001841 ALOGE("ERR(%s):jpegEnc.setOutBuf() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001842 goto jpeg_encode_done;
1843 }
1844
1845 if (jpegEnc.updateConfig()) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001846 ALOGE("ERR(%s):jpegEnc.updateConfig() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001847 goto jpeg_encode_done;
1848 }
1849
1850 if (jpegEnc.encode((int *)&jpegBuf->size.s, &mExifInfo)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001851 ALOGE("ERR(%s):jpegEnc.encode() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001852 goto jpeg_encode_done;
1853 }
1854
1855 ret = true;
1856
1857jpeg_encode_done:
1858
1859 if (jpegEnc.flagCreate() == true)
1860 jpegEnc.destroy();
1861
1862 return ret;
1863}
1864
1865bool ExynosCamera::autoFocus(void)
1866{
1867 if (m_previewDev->fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001868 ALOGE("ERR(%s):Camera was closed", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001869 return false;
1870 }
1871
1872 if (m_flagAutoFocusRunning == true) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001873 ALOGD("DEBUG(%s):m_flagAutoFocusRunning == true", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001874 return true;
1875 }
1876
1877 switch (m_curCameraInfo->focusMode) {
1878 case FOCUS_MODE_AUTO:
1879 case FOCUS_MODE_INFINITY:
1880 case FOCUS_MODE_MACRO:
1881 if (m_touchAFMode == true) {
1882 if (setFocusMode(FOCUS_MODE_TOUCH) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001883 ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001884 return false;
1885 }
1886 } else {
1887 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001888 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001889 return false;
1890 }
1891 }
1892 break;
1893 case FOCUS_MODE_CONTINUOUS_VIDEO:
1894 case FOCUS_MODE_CONTINUOUS_PICTURE:
1895 /* Doing nothing. Because we assume that continuous focus mode is
1896 always focused on. */
1897 break;
1898 case FOCUS_MODE_TOUCH:
1899 if (setFocusMode(FOCUS_MODE_TOUCH) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001900 ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001901 return false;
1902 }
1903 break;
1904 case FOCUS_MODE_FIXED:
1905 break;
1906 case FOCUS_MODE_EDOF:
1907 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07001908 ALOGE("ERR(%s):Unsupported value(%d)", __func__, m_curCameraInfo->focusMode);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001909 return false;
1910 break;
1911 }
1912
1913 m_flagAutoFocusRunning = true;
1914
1915 return true;
1916}
1917
1918bool ExynosCamera::cancelAutoFocus(void)
1919{
1920 if (m_previewDev->fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001921 ALOGE("ERR(%s):Camera was closed", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001922 return false;
1923 }
1924
1925 if (m_flagAutoFocusRunning == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001926 ALOGV("DEBUG(%s):m_flagAutoFocusRunning == false", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001927 return true;
1928 }
1929
1930 switch (m_curCameraInfo->focusMode) {
1931 case FOCUS_MODE_AUTO:
1932 case FOCUS_MODE_INFINITY:
1933 case FOCUS_MODE_MACRO:
1934 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001935 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001936 return false;
1937 }
1938 break;
1939 case FOCUS_MODE_CONTINUOUS_VIDEO:
1940 case FOCUS_MODE_CONTINUOUS_PICTURE:
1941 /* Doing nothing. Because we assume that continuous focus mode is
1942 always focused on. */
1943 break;
1944 case FOCUS_MODE_TOUCH:
1945 if (setFocusMode(FOCUS_MODE_TOUCH) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001946 ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001947 return false;
1948 }
1949 m_touchAFMode = false;
1950 break;
1951 case FOCUS_MODE_FIXED:
1952 break;
1953 case FOCUS_MODE_EDOF:
1954 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07001955 ALOGE("ERR(%s):Unsupported value(%d)", __func__, m_curCameraInfo->focusMode);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001956 return false;
1957 break;
1958 }
1959
1960 m_flagAutoFocusRunning = false;
1961
1962 return true;
1963}
1964
1965int ExynosCamera::getFucusModeResult(void)
1966{
1967 int ret = 0;
1968
1969#define AF_WATING_TIME (100000) // 100msec
1970#define TOTAL_AF_WATING_TIME (2000000) // 2000msec
1971
1972 for (unsigned int i = 0; i < TOTAL_AF_WATING_TIME; i += AF_WATING_TIME) {
1973
1974 if (m_flagAutoFocusRunning == false)
1975 return -1;
1976
1977 if (exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT, &ret) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07001978 ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07001979 return -1;
1980 }
1981
1982 if (strcmp((const char*)m_cameraName, "S5K4E5") == 0) {
1983 switch(ret) {
1984 case 0x00: // AF Running
1985 ret = 0;
1986 break;
1987 case 0x02: // AF succeed
1988 ret = 1;
1989 break;
1990 case 0x01:
1991 default : // AF fail
1992 ret = -1;
1993 break;
1994 }
1995
1996 if (ret != 0)
1997 break;
1998
1999 } else if (strcmp((const char*)m_cameraName, "M5M0") == 0) {
2000 switch(ret) {
2001 case 0x00: // AF Running
2002 ret = 0;
2003 break;
2004 case 0x01: // AF succeed
2005 ret = 1;
2006 break;
2007 case 0x02: // AF cancel
2008 ret = 0;
2009 break;
2010 default: // AF fail
2011 ret = -1;
2012 break;
2013 }
2014
2015 if (ret != 0)
2016 break;
2017 } else {
2018 ret = -1;
2019 break;
2020 }
2021
2022 usleep(AF_WATING_TIME);
2023 }
2024
2025 return ret;
2026}
2027
2028bool ExynosCamera::startFaceDetection(void)
2029{
2030 if (m_flagStartFaceDetection == true) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002031 ALOGD("DEBUG(%s):Face detection already started..", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002032 return true;
2033 }
2034
2035 if (m_previewDev->flagStart == true) {
2036 //if (this->setFocusMode(FOCUS_MODE_AUTO) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07002037 // ALOGE("ERR(%s):Fail setFocusMode", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002038
2039 if (m_internalISP == true) {
2040 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_FD_SET_MAX_FACE_NUMBER, m_defaultCameraInfo->maxNumDetectedFaces) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002041 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002042 return false;
2043 }
2044
2045 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_START) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002046 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002047 return false;
2048 }
2049 } else {
2050 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACE_DETECTION, FACE_DETECTION_ON) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002051 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002052 return false;
2053 }
2054 }
2055 m_flagStartFaceDetection = true;
2056 }
2057 return true;
2058}
2059
2060bool ExynosCamera::stopFaceDetection(void)
2061{
2062 if (m_flagStartFaceDetection == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002063 ALOGD("DEBUG(%s):Face detection already stopped..", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002064 return true;
2065 }
2066
2067 if (m_previewDev->flagStart == true) {
2068 if (m_internalISP == true) {
2069 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_STOP) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002070 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002071 return false;
2072 }
2073 } else {
2074 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACE_DETECTION, FACE_DETECTION_OFF) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002075 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002076 return false;
2077 }
2078 }
2079 m_flagStartFaceDetection = false;
2080 }
2081 return true;
2082}
2083
2084bool ExynosCamera::flagStartFaceDetection(void)
2085{
2086 return m_flagStartFaceDetection;
2087}
2088
2089bool ExynosCamera::setFaceDetectLock(bool toggle)
2090{
2091 int lock = (toggle == true) ? 1 : 0;
2092
2093 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, lock) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002094 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002095 return false;
2096 }
2097 return true;
2098}
2099
2100bool ExynosCamera::startSmoothZoom(int value)
2101{
2102 if (m_defaultCameraInfo->hwZoomSupported == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002103 ALOGE("ERR(%s):m_defaultCameraInfo->hwZoomSupported == false", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002104 return false;
2105 }
2106
2107 return this->setZoom(value);
2108}
2109
2110bool ExynosCamera::stopSmoothZoom(void)
2111{
2112 // TODO
2113 return true;
2114}
2115
2116int ExynosCamera::getAntibanding(void)
2117{
2118 return m_curCameraInfo->antiBanding;
2119}
2120
2121bool ExynosCamera::getAutoExposureLock(void)
2122{
2123 return m_curCameraInfo->autoExposureLock;
2124}
2125
2126bool ExynosCamera::getAutoWhiteBalanceLock(void)
2127{
2128 return m_curCameraInfo->autoWhiteBalanceLock;
2129}
2130
2131int ExynosCamera::getColorEffect(void)
2132{
2133 return m_curCameraInfo->effect;
2134}
2135
2136int ExynosCamera::getDetectedFacesAreas(int num,
2137 int *id,
2138 int *score,
2139 ExynosRect *face,
2140 ExynosRect *leftEye,
2141 ExynosRect *rightEye,
2142 ExynosRect *mouth)
2143{
2144 if (m_defaultCameraInfo->maxNumDetectedFaces == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002145 ALOGE("ERR(%s):maxNumDetectedFaces == 0 fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002146 return -1;
2147 }
2148
2149 if (m_flagStartFaceDetection == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002150 ALOGD("DEBUG(%s):m_flagStartFaceDetection == false", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002151 return 0;
2152 }
2153
2154 if (m_defaultCameraInfo->maxNumDetectedFaces < num)
2155 num = m_defaultCameraInfo->maxNumDetectedFaces;
2156
2157 // width : 0 ~ previewW
2158 // height : 0 ~ previewH
2159 // if eye, mouth is not detectable : -1, -1
2160 ExynosRect2 *face2 = new ExynosRect2[num];
2161 ExynosRect2 *leftEye2 = new ExynosRect2[num];
2162 ExynosRect2 *rightEye2 = new ExynosRect2[num];
2163 ExynosRect2 *mouth2 = new ExynosRect2[num];
2164
2165 num = getDetectedFacesAreas(num, id, score, face2, leftEye2, rightEye2, mouth2);
2166
2167 for (int i = 0; i < num; i++) {
2168
2169 m_secRect22SecRect(&face2[i], &face[i]);
2170 face[i].fullW = m_curCameraInfo->previewW;
2171 face[i].fullH = m_curCameraInfo->previewH;
2172
2173 m_secRect22SecRect(&leftEye2[i], &leftEye[i]);
2174 leftEye[i].fullW = m_curCameraInfo->previewW;
2175 leftEye[i].fullH = m_curCameraInfo->previewH;
2176
2177 m_secRect22SecRect(&rightEye2[i], &rightEye[i]);
2178 rightEye[i].fullW = m_curCameraInfo->previewW;
2179 rightEye[i].fullH = m_curCameraInfo->previewH;
2180
2181 m_secRect22SecRect(&mouth2[i], &mouth[i]);
2182 mouth[i].fullW = m_curCameraInfo->previewW;
2183 mouth[i].fullH = m_curCameraInfo->previewH;
2184 }
2185
2186 delete [] face2;
2187 delete [] leftEye2;
2188 delete [] rightEye2;
2189 delete [] mouth2;
2190
2191 return num;
2192}
2193
2194int ExynosCamera::getDetectedFacesAreas(int num,
2195 int *id,
2196 int *score,
2197 ExynosRect2 *face,
2198 ExynosRect2 *leftEye,
2199 ExynosRect2 *rightEye,
2200 ExynosRect2 *mouth)
2201{
2202 if (m_defaultCameraInfo->maxNumDetectedFaces == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002203 ALOGE("ERR(%s):maxNumDetectedFaces == 0 fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002204 return -1;
2205 }
2206
2207 if (m_flagStartFaceDetection == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002208 ALOGD("DEBUG(%s):m_flagStartFaceDetection == false", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002209 return 0;
2210 }
2211
2212 int i = 0;
2213
2214 if (m_defaultCameraInfo->maxNumDetectedFaces < num)
2215 num = m_defaultCameraInfo->maxNumDetectedFaces;
2216
2217 const unsigned int numOfFDEntity = 1 + ((V4L2_CID_IS_FD_GET_NEXT - V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER) * num);
2218
2219 // width : 0 ~ previewW
2220 // height : 0 ~ previewH
2221 // if eye, mouth is not detectable : -1, -1
2222 struct v4l2_ext_controls fd_ctrls;
2223 struct v4l2_ext_control *fd_ctrl = new struct v4l2_ext_control[numOfFDEntity];
2224 struct v4l2_ext_control *cur_ctrl;
2225
2226 cur_ctrl = &fd_ctrl[0];
2227 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_COUNT;
2228 cur_ctrl++;
2229
2230 for (i = 0; i < num; i++) {
2231 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER;
2232 cur_ctrl++;
2233 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_CONFIDENCE;
2234 cur_ctrl++;
2235 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X;
2236 cur_ctrl++;
2237 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y;
2238 cur_ctrl++;
2239 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X;
2240 cur_ctrl++;
2241 cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y;
2242 cur_ctrl++;
2243 cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X;
2244 cur_ctrl++;
2245 cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y;
2246 cur_ctrl++;
2247 cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X;
2248 cur_ctrl++;
2249 cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y;
2250 cur_ctrl++;
2251 cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X;
2252 cur_ctrl++;
2253 cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y;
2254 cur_ctrl++;
2255 cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X;
2256 cur_ctrl++;
2257 cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y;
2258 cur_ctrl++;
2259 cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X;
2260 cur_ctrl++;
2261 cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y;
2262 cur_ctrl++;
2263 cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X;
2264 cur_ctrl++;
2265 cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y;
2266 cur_ctrl++;
2267 cur_ctrl->id = V4L2_CID_IS_FD_GET_NEXT;
2268 cur_ctrl++;
2269 }
2270
2271 fd_ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
2272 fd_ctrls.count = i + 1;
2273 fd_ctrls.controls = fd_ctrl;
2274
2275 if (exynos_v4l2_g_ext_ctrl(m_previewDev->fd, &fd_ctrls) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002276 ALOGE("ERR(%s):exynos_v4l2_g_ext_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002277 num = -1;
2278 goto done;
2279 }
2280
2281 cur_ctrl = &fd_ctrl[0];
2282 num = cur_ctrl->value;
2283 cur_ctrl++;
2284
2285 for (i = 0; i < num; i++) {
2286 id[i] = cur_ctrl->value;
2287 cur_ctrl++;
2288 score[i] = cur_ctrl->value;
2289 cur_ctrl++;
2290
2291 face[i].x1 = cur_ctrl->value;
2292 cur_ctrl++;
2293 face[i].y1 = cur_ctrl->value;
2294 cur_ctrl++;
2295 face[i].x2 = cur_ctrl->value;
2296 cur_ctrl++;
2297 face[i].y2 = cur_ctrl->value;
2298 cur_ctrl++;
2299
2300 leftEye[i].x1 = cur_ctrl->value;
2301 cur_ctrl++;
2302 leftEye[i].y1 = cur_ctrl->value;
2303 cur_ctrl++;
2304 leftEye[i].x2 = cur_ctrl->value;
2305 cur_ctrl++;
2306 leftEye[i].y2 = cur_ctrl->value;
2307 cur_ctrl++;
2308
2309 rightEye[i].x1 = cur_ctrl->value;
2310 cur_ctrl++;
2311 rightEye[i].y1 = cur_ctrl->value;
2312 cur_ctrl++;
2313 rightEye[i].x2 = cur_ctrl->value;
2314 cur_ctrl++;
2315 rightEye[i].y2 = cur_ctrl->value;
2316 cur_ctrl++;
2317
2318 mouth[i].x1 = cur_ctrl->value;
2319 cur_ctrl++;
2320 mouth[i].y1 = cur_ctrl->value;
2321 cur_ctrl++;
2322 mouth[i].x2 = cur_ctrl->value;
2323 cur_ctrl++;
2324 mouth[i].y2 = cur_ctrl->value;
2325 cur_ctrl++;
2326 }
2327
2328done:
2329 delete [] fd_ctrl;
2330
2331 return num;
2332}
2333
2334int ExynosCamera::getExposureCompensation(void)
2335{
2336 return m_curCameraInfo->exposure;
2337}
2338
2339float ExynosCamera::getExposureCompensationStep(void)
2340{
2341 // CameraParameters.h
2342 // The exposure compensation step. Exposure compensation index multiply by
2343 // step eqals to EV. Ex: if exposure compensation index is 6 and step is
2344 // 0.3333, EV is -2.
2345 // Example value: "0.333333333" or "0.5". Read only.
2346 // -> But, this formula doesn't works in apps.
2347 return 1.0f;
2348}
2349
2350int ExynosCamera::getFlashMode(void)
2351{
2352 return m_curCameraInfo->flashMode;
2353}
2354
2355bool ExynosCamera::getFocalLength(int *num, int *den)
2356{
2357 *num = m_defaultCameraInfo->focalLengthNum;
2358 *num = m_defaultCameraInfo->focalLengthDen;
2359 return true;
2360}
2361
2362int ExynosCamera::getFocusAreas(ExynosRect *rects)
2363{
2364 // TODO
2365 return 0;
2366}
2367
2368int ExynosCamera::getFocusDistances(float *output)
2369{
2370 // TODO
2371 return 0;
2372}
2373
2374int ExynosCamera::getFocusMode(void)
2375{
2376 return m_curCameraInfo->focusMode;
2377}
2378
2379float ExynosCamera::getHorizontalViewAngle(void)
2380{
2381 //TODO
2382 return 51.2f;
2383}
2384
2385int ExynosCamera::getJpegQuality(void)
2386{
2387 return m_jpegQuality;
2388}
2389
2390int ExynosCamera::getJpegThumbnailQuality(void)
2391{
2392 return m_jpegThumbnailQuality;
2393}
2394
2395bool ExynosCamera::getJpegThumbnailSize(int *w, int *h)
2396{
2397 *w = m_curCameraInfo->thumbnailW;
2398 *h = m_curCameraInfo->thumbnailH;
2399 return true;
2400}
2401
2402int ExynosCamera::getMaxExposureCompensation(void)
2403{
2404 return m_defaultCameraInfo->maxExposure;
2405}
2406
2407int ExynosCamera::getMaxNumDetectedFaces(void)
2408{
2409 return m_defaultCameraInfo->maxNumDetectedFaces;
2410}
2411
2412int ExynosCamera::getMaxNumFocusAreas(void)
2413{
2414 return m_defaultCameraInfo->maxNumFocusAreas;
2415}
2416
2417int ExynosCamera::getMaxNumMeteringAreas(void)
2418{
2419 return m_defaultCameraInfo->maxNumMeteringAreas;
2420}
2421
2422int ExynosCamera::getMaxZoom(void)
2423{
2424 return m_defaultCameraInfo->maxZoom;
2425}
2426
2427int ExynosCamera::getMeteringAreas(ExynosRect *rects)
2428{
2429 // TODO
2430 return 0;
2431}
2432
2433int ExynosCamera::getMinExposureCompensation(void)
2434{
2435 return m_defaultCameraInfo->minExposure;
2436}
2437
2438int ExynosCamera::getPictureFormat(void)
2439{
2440 return m_curCameraInfo->pictureColorFormat;
2441}
2442
2443bool ExynosCamera::getPictureSize(int *w, int *h)
2444{
2445 *w = m_curCameraInfo->pictureW;
2446 *h = m_curCameraInfo->pictureH;
2447 return true;
2448}
2449
2450int ExynosCamera::getPreviewFormat(void)
2451{
2452 return m_curCameraInfo->previewColorFormat;
2453}
2454
2455bool ExynosCamera::getPreviewFpsRange(int *min, int *max)
2456{
2457 *min = 1;
2458 *max = m_defaultCameraInfo->fps;
2459 return true;
2460}
2461
2462int ExynosCamera::getPreviewFrameRate(void)
2463{
2464 return m_curCameraInfo->fps;
2465}
2466
2467bool ExynosCamera::getPreviewSize(int *w, int *h)
2468{
2469 *w = m_curCameraInfo->previewW;
2470 *h = m_curCameraInfo->previewH;
2471 return true;
2472}
2473
2474int ExynosCamera::getSceneMode(void)
2475{
2476 return m_curCameraInfo->sceneMode;
2477}
2478
2479int ExynosCamera::getSupportedAntibanding(void)
2480{
2481 return m_defaultCameraInfo->antiBandingList;
2482}
2483
2484int ExynosCamera::getSupportedColorEffects(void)
2485{
2486 return m_defaultCameraInfo->effectList;
2487}
2488
2489int ExynosCamera::getSupportedFlashModes(void)
2490{
2491 return m_defaultCameraInfo->flashModeList;
2492}
2493
2494int ExynosCamera::getSupportedFocusModes(void)
2495{
2496 return m_defaultCameraInfo->focusModeList;
2497}
2498
2499bool ExynosCamera::getSupportedJpegThumbnailSizes(int *w, int *h)
2500{
2501 *w = m_defaultCameraInfo->thumbnailW;
2502 *h = m_defaultCameraInfo->thumbnailH;
2503 return true;
2504}
2505
2506bool ExynosCamera::getSupportedPictureSizes(int *w, int *h)
2507{
2508 *w = m_defaultCameraInfo->pictureW;
2509 *h = m_defaultCameraInfo->pictureH;
2510 return true;
2511}
2512
2513bool ExynosCamera::getSupportedPreviewSizes(int *w, int *h)
2514{
2515 *w = m_defaultCameraInfo->previewW;
2516 *h = m_defaultCameraInfo->previewH;
2517 return true;
2518}
2519
2520int ExynosCamera::getSupportedSceneModes(void)
2521{
2522 return m_defaultCameraInfo->sceneModeList;
2523}
2524
2525bool ExynosCamera::getSupportedVideoSizes(int *w, int *h)
2526{
2527 *w = m_defaultCameraInfo->videoW;
2528 *h = m_defaultCameraInfo->videoH;
2529 return true;
2530}
2531
2532bool ExynosCamera::getPreferredPreivewSizeForVideo(int *w, int *h)
2533{
2534 *w = m_defaultCameraInfo->prefVideoPreviewW;
2535 *h = m_defaultCameraInfo->prefVideoPreviewH;
2536 return true;
2537}
2538
2539int ExynosCamera::getSupportedWhiteBalance(void)
2540{
2541 return m_defaultCameraInfo->whiteBalanceList;
2542}
2543
2544float ExynosCamera::getVerticalViewAngle(void)
2545{
2546 // TODO
2547 return 39.4f;
2548}
2549
2550bool ExynosCamera::getVideoStabilization(void)
2551{
2552 return m_curCameraInfo->videoStabilization;
2553}
2554
2555int ExynosCamera::getWhiteBalance(void)
2556{
2557 return m_curCameraInfo->whiteBalance;
2558}
2559
2560int ExynosCamera::getZoom(void)
2561{
2562 return m_curCameraInfo->zoom;
2563}
2564
2565int ExynosCamera::getMaxZoomRatio(void)
2566{
2567 return 400;
2568}
2569
2570bool ExynosCamera::isAutoExposureLockSupported(void)
2571{
2572 return m_defaultCameraInfo->autoExposureLockSupported;
2573}
2574
2575bool ExynosCamera::isAutoWhiteBalanceLockSupported(void)
2576{
2577 return m_defaultCameraInfo->autoWhiteBalanceLockSupported;
2578}
2579
2580bool ExynosCamera::isSmoothZoomSupported(void)
2581{
2582 if (m_defaultCameraInfo->hwZoomSupported == true)
2583 return true;
2584 else
2585 return false;
2586}
2587
2588bool ExynosCamera::isVideoSnapshotSupported(void)
2589{
2590 return true;
2591}
2592
2593bool ExynosCamera::isVideoStabilizationSupported(void)
2594{
2595 return m_defaultCameraInfo->supportVideoStabilization;
2596}
2597
2598bool ExynosCamera::isZoomSupported(void)
2599{
2600 return true;
2601}
2602
2603bool ExynosCamera::setAntibanding(int value)
2604{
2605 int internalValue = -1;
2606
2607 switch (value) {
2608 case ANTIBANDING_AUTO:
2609 internalValue = ::ANTI_BANDING_AUTO;
2610 break;
2611 case ANTIBANDING_50HZ:
2612 internalValue = ::ANTI_BANDING_50HZ;
2613 break;
2614 case ANTIBANDING_60HZ:
2615 internalValue = ::ANTI_BANDING_60HZ;
2616 break;
2617 case ANTIBANDING_OFF:
2618 internalValue = ::ANTI_BANDING_OFF;
2619 break;
2620 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07002621 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002622 return false;
2623 break;
2624 }
2625
2626 if (m_internalISP == true) {
2627 if (internalValue < ::IS_AFC_DISABLE || ::IS_AFC_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002628 ALOGE("ERR(%s):Invalid value (%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002629 return false;
2630 }
2631 } else {
2632 if (internalValue < ::ANTI_BANDING_AUTO || ::ANTI_BANDING_OFF < internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002633 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002634 return false;
2635 }
2636 }
2637
2638 if (m_curCameraInfo->antiBanding != value) {
2639 m_curCameraInfo->antiBanding = value;
2640 if (m_flagCreate == true) {
2641 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_AFC_MODE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002642 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002643 return false;
2644 }
2645 }
2646 }
2647
2648 return true;
2649}
2650
2651bool ExynosCamera::setAutoExposureLock(bool toggle)
2652{
2653 int internalValue = -1;
2654
2655 if (m_curCameraInfo->autoExposureLock == toggle)
2656 return true;
2657
2658 m_curCameraInfo->autoExposureLock = toggle;
2659
2660 if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == true)
2661 internalValue = AE_LOCK_AWB_LOCK;
2662 else if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == false)
2663 internalValue = AE_LOCK_AWB_UNLOCK;
2664 else if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == true)
2665 internalValue = AE_UNLOCK_AWB_LOCK;
2666 else // if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == false)
2667 internalValue = AE_UNLOCK_AWB_UNLOCK;
2668
2669 if (m_flagCreate == true) {
2670 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002671 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002672 return false;
2673 }
2674 }
2675 return true;
2676}
2677
2678bool ExynosCamera::setAutoWhiteBalanceLock(bool toggle)
2679{
2680 int internalValue = -1;
2681
2682 if (m_curCameraInfo->autoWhiteBalanceLock == toggle)
2683 return true;
2684
2685 m_curCameraInfo->autoWhiteBalanceLock = toggle;
2686
2687 if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == true)
2688 internalValue = AE_LOCK_AWB_LOCK;
2689 else if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == false)
2690 internalValue = AE_LOCK_AWB_UNLOCK;
2691 else if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == true)
2692 internalValue = AE_UNLOCK_AWB_LOCK;
2693 else // if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == false)
2694 internalValue = AE_UNLOCK_AWB_UNLOCK;
2695
2696 if (m_flagCreate == true) {
2697 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002698 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002699 return false;
2700 }
2701 }
2702 return true;
2703}
2704
2705bool ExynosCamera::setColorEffect(int value)
2706{
2707 int internalValue = -1;
2708
2709 switch (value) {
2710 case EFFECT_NONE:
2711 if (m_internalISP == true)
2712 internalValue = ::IS_IMAGE_EFFECT_DISABLE;
2713 else
2714 internalValue = ::IMAGE_EFFECT_NONE;
2715 break;
2716 case EFFECT_MONO:
2717 if (m_internalISP == true)
2718 internalValue = ::IS_IMAGE_EFFECT_MONOCHROME;
2719 else
2720 internalValue = ::IMAGE_EFFECT_BNW;
2721 break;
2722 case EFFECT_NEGATIVE:
2723 internalValue = IS_IMAGE_EFFECT_NEGATIVE_MONO;
2724 break;
2725 case EFFECT_SEPIA:
2726 if (m_internalISP == true)
2727 internalValue = ::IS_IMAGE_EFFECT_SEPIA;
2728 else
2729 internalValue = ::IMAGE_EFFECT_SEPIA;
2730 break;
2731 case EFFECT_AQUA:
2732 case EFFECT_SOLARIZE:
2733 case EFFECT_POSTERIZE:
2734 case EFFECT_WHITEBOARD:
2735 case EFFECT_BLACKBOARD:
2736 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07002737 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002738 return false;
2739 break;
2740 }
2741
2742 if (m_internalISP == true) {
2743 if (internalValue < ::IS_IMAGE_EFFECT_DISABLE || ::IS_IMAGE_EFFECT_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002744 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002745 return false;
2746 }
2747 } else {
2748 if (internalValue <= ::IMAGE_EFFECT_BASE || ::IMAGE_EFFECT_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002749 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002750 return false;
2751 }
2752 }
2753
2754 if (m_curCameraInfo->effect != value) {
2755 m_curCameraInfo->effect = value;
2756 if (m_flagCreate == true) {
2757 if (m_internalISP == true) {
2758 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_IMAGE_EFFECT, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002759 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002760 return false;
2761 }
2762 } else {
2763 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_EFFECT, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002764 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002765 return false;
2766 }
2767 }
2768 }
2769 }
2770
2771 return true;
2772}
2773
2774bool ExynosCamera::setExposureCompensation(int value)
2775{
2776 int internalValue = value;
2777
2778 if (m_internalISP == true) {
2779 internalValue += IS_EXPOSURE_DEFAULT;
2780 if (internalValue < IS_EXPOSURE_MINUS_2 || IS_EXPOSURE_PLUS_2 < internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002781 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002782 return false;
2783 }
2784 } else {
2785 internalValue += EV_DEFAULT;
2786 if (internalValue < EV_MINUS_4 || EV_PLUS_4 < internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002787 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002788 return false;
2789 }
2790 }
2791
2792 if (m_curCameraInfo->exposure != value) {
2793 m_curCameraInfo->exposure = value;
2794 if (m_flagCreate == true) {
2795 if (m_internalISP == true) {
2796 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_EXPOSURE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002797 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002798 return false;
2799 }
2800 } else {
2801 if (this->setBrightness(value) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002802 ALOGE("ERR(%s):setBrightness() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002803 return false;
2804 }
2805 }
2806 }
2807 }
2808
2809 return true;
2810}
2811
2812bool ExynosCamera::setFlashMode(int value)
2813{
2814 int internalValue = -1;
2815
2816 switch (value) {
2817 case FLASH_MODE_OFF:
2818 internalValue = ::FLASH_MODE_OFF;
2819 break;
2820 case FLASH_MODE_AUTO:
2821 internalValue = ::FLASH_MODE_AUTO;
2822 break;
2823 case FLASH_MODE_ON:
2824 internalValue = ::FLASH_MODE_ON;
2825 break;
2826 case FLASH_MODE_TORCH:
2827 internalValue = ::FLASH_MODE_TORCH;
2828 break;
2829 case FLASH_MODE_RED_EYE:
2830 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07002831 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002832 return false;
2833 break;
2834 }
2835
2836 if (internalValue <= ::FLASH_MODE_BASE || ::FLASH_MODE_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002837 ALOGE("ERR(%s):Invalid value (%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002838 return false;
2839 }
2840
2841 if (m_curCameraInfo->flashMode != value) {
2842 m_curCameraInfo->flashMode = value;
2843 if (m_flagCreate == true) {
2844 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FLASH_MODE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002845 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002846 return false;
2847 }
2848 }
2849 }
2850
2851 return true;
2852}
2853
2854bool ExynosCamera::setFocusAreas(int num, ExynosRect* rects, int *weights)
2855{
2856 if (m_defaultCameraInfo->maxNumFocusAreas == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002857 ALOGV("DEBUG(%s):maxNumFocusAreas is 0. so, ignored", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002858 return true;
2859 }
2860
2861 bool ret = true;
2862
2863 ExynosRect2 *rect2s = new ExynosRect2[num];
2864 for (int i = 0; i < num; i++)
2865 m_secRect2SecRect2(&rects[i], &rect2s[i]);
2866
2867 ret = setFocusAreas(num, rect2s, weights);
2868
2869 delete [] rect2s;
2870
2871 return ret;
2872}
2873
2874bool ExynosCamera::setFocusAreas(int num, ExynosRect2* rect2s, int *weights)
2875{
2876 if (m_defaultCameraInfo->maxNumFocusAreas == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002877 ALOGV("DEBUG(%s):maxNumFocusAreas is 0. so, ignored", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002878 return true;
2879 }
2880
2881 int new_x = 0;
2882 int new_y = 0;
2883
2884 if (m_defaultCameraInfo->maxNumFocusAreas < num)
2885 num = m_defaultCameraInfo->maxNumFocusAreas;
2886
2887 if (m_flagCreate == true) {
2888 for (int i = 0; i < num; i++) {
2889 if ( num == 1
2890 && rect2s[0].x1 == 0
2891 && rect2s[0].y1 == 0
2892 && rect2s[0].x2 == m_curCameraInfo->previewW
2893 && rect2s[0].y2 == m_curCameraInfo->previewH) {
2894 // TODO : driver decide focus areas -> focus center.
2895 new_x = (m_curCameraInfo->previewW) / 2;
2896 new_y = (m_curCameraInfo->previewH) / 2;
2897 } else {
2898 new_x = (rect2s[i].x1 + rect2s[i].x2) / 2;
2899 new_y = (rect2s[i].y1 + rect2s[i].y2) / 2;
2900 }
2901
2902 m_touchAFMode = true;
2903 if ( exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, new_x) < 0
2904 && exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, new_y) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002905 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002906 return false;
2907 }
2908 }
2909 }
2910
2911 return true;
2912}
2913
2914bool ExynosCamera::setFocusMode(int value)
2915{
2916 int internalValue = -1;
2917
2918 switch (value) {
2919 case FOCUS_MODE_AUTO:
2920 internalValue = ::FOCUS_MODE_AUTO;
2921 m_touchAFMode = false;
2922 break;
2923 case FOCUS_MODE_INFINITY:
2924 internalValue = ::FOCUS_MODE_INFINITY;
2925 m_touchAFMode = false;
2926 break;
2927 case FOCUS_MODE_MACRO:
2928 internalValue = ::FOCUS_MODE_MACRO;
2929 m_touchAFMode = false;
2930 break;
2931 case FOCUS_MODE_CONTINUOUS_VIDEO:
2932 case FOCUS_MODE_CONTINUOUS_PICTURE:
2933 internalValue = ::FOCUS_MODE_CONTINOUS;
2934 m_touchAFMode = false;
2935 break;
2936 case FOCUS_MODE_TOUCH:
2937 internalValue = ::FOCUS_MODE_TOUCH;
2938 m_touchAFMode = true;
2939 break;
2940 case FOCUS_MODE_FIXED:
2941 internalValue = ::FOCUS_MODE_FIXED;
2942 m_touchAFMode = false;
2943 break;
2944 case FOCUS_MODE_EDOF:
2945 default:
2946 m_touchAFMode = false;
Dima Zavinf4979f52012-05-01 21:49:24 -07002947 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002948 return false;
2949 break;
2950 }
2951
2952 if (::FOCUS_MODE_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002953 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002954 return false;
2955 }
2956
2957 if (m_curCameraInfo->focusMode != value) {
2958 m_curCameraInfo->focusMode = value;
2959 if (m_flagCreate == true) {
2960 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FOCUS_MODE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07002961 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07002962 return false;
2963 }
2964 }
2965 }
2966
2967 return true;
2968}
2969
2970bool ExynosCamera::setGpsAltitude(const char *gpsAltitude)
2971{
2972 double conveted_altitude = 0;
2973
2974 if (gpsAltitude == NULL)
2975 m_curCameraInfo->gpsAltitude = 0;
2976 else {
2977 conveted_altitude = atof(gpsAltitude);
2978 m_curCameraInfo->gpsAltitude = (long)(conveted_altitude * 100 / 1);
2979 }
2980
2981 return true;
2982}
2983
2984bool ExynosCamera::setGpsLatitude(const char *gpsLatitude)
2985{
2986 double conveted_latitude = 0;
2987
2988 if (gpsLatitude == NULL)
2989 m_curCameraInfo->gpsLatitude = 0;
2990 else {
2991 conveted_latitude = atof(gpsLatitude);
2992 m_curCameraInfo->gpsLatitude = (long)(conveted_latitude * 10000 / 1);
2993 }
2994
2995 return true;
2996}
2997
2998bool ExynosCamera::setGpsLongitude(const char *gpsLongitude)
2999{
3000 double conveted_longitude = 0;
3001
3002 if (gpsLongitude == NULL)
3003 m_curCameraInfo->gpsLongitude = 0;
3004 else {
3005 conveted_longitude = atof(gpsLongitude);
3006 m_curCameraInfo->gpsLongitude = (long)(conveted_longitude * 10000 / 1);
3007 }
3008
3009 return true;
3010}
3011
3012bool ExynosCamera::setGpsProcessingMethod(const char *gpsProcessingMethod)
3013{
3014 memset(mExifInfo.gps_processing_method, 0, sizeof(mExifInfo.gps_processing_method));
3015
3016 if (gpsProcessingMethod != NULL) {
3017 size_t len = strlen(gpsProcessingMethod);
3018 if (len > sizeof(mExifInfo.gps_processing_method)) {
3019 len = sizeof(mExifInfo.gps_processing_method);
3020 }
3021 memcpy(mExifInfo.gps_processing_method, gpsProcessingMethod, len);
3022 }
3023
3024 return true;
3025}
3026
3027bool ExynosCamera::setGpsTimeStamp(const char *gpsTimestamp)
3028{
3029 if (gpsTimestamp == NULL)
3030 m_curCameraInfo->gpsTimestamp = 0;
3031 else
3032 m_curCameraInfo->gpsTimestamp = atol(gpsTimestamp);
3033
3034 return true;
3035}
3036
3037bool ExynosCamera::setJpegQuality(int quality)
3038{
3039 if (quality < JPEG_QUALITY_MIN || JPEG_QUALITY_MAX < quality) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003040 ALOGE("ERR(%s):Invalid quality (%d)", __func__, quality);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003041 return false;
3042 }
3043
3044 m_jpegQuality = quality;
3045
3046 return true;
3047}
3048
3049bool ExynosCamera::setJpegThumbnailQuality(int quality)
3050{
3051 if (quality < JPEG_QUALITY_MIN || JPEG_QUALITY_MAX < quality) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003052 ALOGE("ERR(%s):Invalid quality (%d)", __func__, quality);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003053 return false;
3054 }
3055
3056 m_jpegThumbnailQuality = quality;
3057
3058 return true;
3059}
3060
3061bool ExynosCamera::setJpegThumbnailSize(int w, int h)
3062{
3063 m_curCameraInfo->thumbnailW = w;
3064 m_curCameraInfo->thumbnailH = h;
3065 return true;
3066}
3067
3068bool ExynosCamera::setMeteringAreas(int num, ExynosRect *rects, int *weights)
3069{
3070 if (m_defaultCameraInfo->maxNumMeteringAreas == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003071 ALOGV("DEBUG(%s):maxNumMeteringAreas is 0. so, ignored", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003072 return true;
3073 }
3074
3075 if (m_defaultCameraInfo->maxNumMeteringAreas < num)
3076 num = m_defaultCameraInfo->maxNumMeteringAreas;
3077
3078 if (m_flagCreate == true) {
3079 for (int i = 0; i < num; i++) {
3080 if ( exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_METERING_POSITION_X, rects[i].x) < 0
3081 && exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_METERING_POSITION_Y, rects[i].y) < 0
3082 && exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_METERING_WINDOW_X, rects[i].w) < 0
3083 && exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_METERING_WINDOW_Y, rects[i].h) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003084 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003085 return false;
3086 }
3087 }
3088 }
3089
3090 return true;
3091}
3092
3093bool ExynosCamera::setMeteringAreas(int num, ExynosRect2 *rect2s, int *weights)
3094{
3095 if (m_defaultCameraInfo->maxNumMeteringAreas == 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003096 ALOGV("DEBUG(%s):maxNumMeteringAreas is 0. so, ignored", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003097 return true;
3098 }
3099
3100 bool ret = true;
3101
3102 ExynosRect *rects = new ExynosRect[num];
3103 for (int i = 0; i < num; i++)
3104 m_secRect22SecRect(&rect2s[i], &rects[i]);
3105
3106 /* FIXME: Currnetly HW dose not support metering area */
3107 //ret = setMeteringAreas(num, rects, weights);
3108
3109 delete [] rects;
3110
3111 return ret;
3112}
3113
3114bool ExynosCamera::setPictureFormat(int colorFormat)
3115{
3116 m_curCameraInfo->pictureColorFormat = colorFormat;
3117
3118#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
3119 m_printFormat(m_curCameraInfo->pictureColorFormat, "PictureFormat");
3120#endif
3121 return true;
3122}
3123
3124bool ExynosCamera::setPictureSize(int w, int h)
3125{
3126 m_curCameraInfo->pictureW = w;
3127 m_curCameraInfo->pictureH = h;
3128
3129 // HACK : Camera cannot support zoom. So, we must make max size picture w, h
3130 m_curCameraInfo->pictureW = m_defaultCameraInfo->pictureW;
3131 m_curCameraInfo->pictureH = m_defaultCameraInfo->pictureH;
3132
3133 return true;
3134}
3135
3136bool ExynosCamera::setPreviewFormat(int colorFormat)
3137{
3138 m_curCameraInfo->previewColorFormat = colorFormat;
3139
3140#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0
3141 m_printFormat(m_curCameraInfo->previewColorFormat, "PreviewtFormat");
3142#endif
3143
3144 return true;
3145}
3146
3147bool ExynosCamera::setPreviewFrameRate(int fps)
3148{
3149 if (fps < FRAME_RATE_AUTO || FRAME_RATE_MAX < fps)
Dima Zavinf4979f52012-05-01 21:49:24 -07003150 ALOGE("ERR(%s):Invalid fps(%d)", __func__, fps);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003151
3152 if (m_flagCreate == true) {
3153 m_curCameraInfo->fps = fps;
3154 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FRAME_RATE, fps) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003155 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003156 return false;
3157 }
3158 }
3159
3160 return true;
3161}
3162
3163bool ExynosCamera::setPreviewSize(int w, int h)
3164{
3165 m_curCameraInfo->previewW = w;
3166 m_curCameraInfo->previewH = h;
3167 return true;
3168}
3169
3170bool ExynosCamera::setRecordingHint(bool hint)
3171{
3172 // TODO : fixed fps?
3173 /* DIS is only possible recording hint is true. */
3174 m_recordingHint = hint;
3175 return true;
3176}
3177
3178bool ExynosCamera::setRotation(int rotation)
3179{
3180 if (rotation < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003181 ALOGE("ERR(%s):Invalid rotation (%d)", __func__, rotation);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003182 return false;
3183 }
3184 m_curCameraInfo->rotation = rotation;
3185
3186 return true;
3187}
3188
3189int ExynosCamera::getRotation(void)
3190{
3191 return m_curCameraInfo->rotation;
3192}
3193
3194bool ExynosCamera::setSceneMode(int value)
3195{
3196 int internalValue = -1;
3197
3198 switch (value) {
3199 case SCENE_MODE_AUTO:
3200 internalValue = ::SCENE_MODE_NONE;
3201 break;
3202 case SCENE_MODE_PORTRAIT:
3203 internalValue = ::SCENE_MODE_PORTRAIT;
3204 break;
3205 case SCENE_MODE_LANDSCAPE:
3206 internalValue = ::SCENE_MODE_LANDSCAPE;
3207 break;
3208 case SCENE_MODE_NIGHT:
3209 internalValue = ::SCENE_MODE_NIGHTSHOT;
3210 break;
3211 case SCENE_MODE_BEACH:
3212 internalValue = ::SCENE_MODE_BEACH_SNOW;
3213 break;
3214 case SCENE_MODE_SNOW:
3215 internalValue = ::SCENE_MODE_BEACH_SNOW;
3216 break;
3217 case SCENE_MODE_SUNSET:
3218 internalValue = ::SCENE_MODE_SUNSET;
3219 break;
3220 case SCENE_MODE_FIREWORKS:
3221 internalValue = ::SCENE_MODE_FIREWORKS;
3222 break;
3223 case SCENE_MODE_SPORTS:
3224 internalValue = ::SCENE_MODE_SPORTS;
3225 break;
3226 case SCENE_MODE_PARTY:
3227 internalValue = ::SCENE_MODE_PARTY_INDOOR;
3228 break;
3229 case SCENE_MODE_CANDLELIGHT:
3230 internalValue = ::SCENE_MODE_CANDLE_LIGHT;
3231 break;
3232 case SCENE_MODE_STEADYPHOTO:
3233 internalValue = ::SCENE_MODE_TEXT;
3234 break;
3235 case SCENE_MODE_ACTION:
3236 case SCENE_MODE_NIGHT_PORTRAIT:
3237 case SCENE_MODE_THEATRE:
3238 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07003239 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003240 return false;
3241 break;
3242 }
3243
3244 if (internalValue <= ::SCENE_MODE_BASE || ::SCENE_MODE_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003245 ALOGE("ERR(%s):Invalid value (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003246 return false;
3247 }
3248
3249 if (m_curCameraInfo->sceneMode != value) {
3250 m_curCameraInfo->sceneMode = value;
3251 if (m_flagCreate == true) {
3252 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SCENE_MODE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003253 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003254 return false;
3255 }
3256 }
3257 }
3258
3259 return true;
3260}
3261
3262bool ExynosCamera::setVideoStabilization(bool toggle)
3263{
3264 m_curCameraInfo->videoStabilization = toggle;
3265
3266 if (m_previewDev->flagStart == true) {
3267 if (m_curCameraInfo->applyVideoStabilization != toggle) {
3268
3269 int dis = (toggle == true) ? CAMERA_DIS_ON : CAMERA_DIS_OFF;
3270
3271 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_DIS, dis) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003272 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003273 return false;
3274 } else {
3275 m_curCameraInfo->applyVideoStabilization = toggle;
3276 }
3277 }
3278 }
3279 return true;
3280}
3281
3282bool ExynosCamera::setWhiteBalance(int value)
3283{
3284 int internalValue = -1;
3285
3286 switch (value) {
3287 case WHITE_BALANCE_AUTO:
3288 if (m_internalISP == true)
3289 internalValue = ::IS_AWB_AUTO;
3290 else
3291 internalValue = ::WHITE_BALANCE_AUTO;
3292 break;
3293 case WHITE_BALANCE_INCANDESCENT:
3294 if (m_internalISP == true)
3295 internalValue = ::IS_AWB_TUNGSTEN;
3296 else
3297 internalValue = ::WHITE_BALANCE_TUNGSTEN;
3298 break;
3299 case WHITE_BALANCE_FLUORESCENT:
3300 if (m_internalISP == true)
3301 internalValue = ::IS_AWB_FLUORESCENT;
3302 else
3303 internalValue = ::WHITE_BALANCE_FLUORESCENT;
3304 break;
3305 case WHITE_BALANCE_DAYLIGHT:
3306 if (m_internalISP == true)
3307 internalValue = ::IS_AWB_DAYLIGHT;
3308 else
3309 internalValue = ::WHITE_BALANCE_SUNNY;
3310 break;
3311 case WHITE_BALANCE_CLOUDY_DAYLIGHT:
3312 if (m_internalISP == true)
3313 internalValue = ::IS_AWB_CLOUDY;
3314 else
3315 internalValue = ::WHITE_BALANCE_CLOUDY;
3316 break;
3317 case WHITE_BALANCE_WARM_FLUORESCENT:
3318 case WHITE_BALANCE_TWILIGHT:
3319 case WHITE_BALANCE_SHADE:
3320 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07003321 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003322 return false;
3323 break;
3324 }
3325
3326 if (m_internalISP == true) {
3327 if (internalValue < ::IS_AWB_AUTO || ::IS_AWB_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003328 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003329 return false;
3330 }
3331 } else {
3332 if (internalValue <= ::WHITE_BALANCE_BASE || ::WHITE_BALANCE_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003333 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003334 return false;
3335 }
3336 }
3337
3338 if (m_curCameraInfo->whiteBalance != value) {
3339 m_curCameraInfo->whiteBalance = value;
3340 if (m_flagCreate == true) {
3341 if (m_internalISP == true) {
3342 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_AWB_MODE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003343 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003344 return false;
3345 }
3346 } else {
3347 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_WHITE_BALANCE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003348 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003349 return false;
3350 }
3351 }
3352 }
3353 }
3354
3355 return true;
3356}
3357
3358bool ExynosCamera::setZoom(int value)
3359{
3360 if (value < ZOOM_LEVEL_0 || ZOOM_LEVEL_MAX <= value) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003361 ALOGE("ERR(%s):Invalid value (%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003362 return false;
3363 }
3364
3365 if (m_curCameraInfo->zoom != value) {
3366 m_curCameraInfo->zoom = value;
3367 if (m_defaultCameraInfo->hwZoomSupported == true) {
3368 if (m_flagCreate == true) {
3369 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_ZOOM, value) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003370 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003371 return false;
3372 }
3373 }
3374 } else {
3375 if (m_setZoom(m_previewDev->fd, m_curCameraInfo->zoom, m_curCameraInfo->previewW, m_curCameraInfo->previewH) == false) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003376 ALOGE("ERR(%s):m_setZoom(%d) fail", __func__, m_curCameraInfo->zoom);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003377 return false;
3378 }
3379 }
3380 }
3381
3382 return true;
3383}
3384
3385bool ExynosCamera::m_setWidthHeight(int mode,
3386 int fd,
3387 struct pollfd *event,
3388 int w,
3389 int h,
3390 int colorFormat,
3391 struct ExynosBuffer *buf,
3392 bool *validBuf)
3393{
3394 // Get and throw away the first frame since it is often garbled.
3395 memset(event, 0, sizeof(struct pollfd));
3396 event->fd = fd;
3397 event->events = POLLIN | POLLERR;
3398
3399 int numOfBuf = 0;
3400
3401 for (int i = 0; i < VIDEO_MAX_FRAME; i++) {
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07003402 if (buf[i].virt.p != NULL || buf[i].phys.p != 0 ||
3403 buf[i].fd.fd >= 0) {
Jiyoung Shin9426c422012-04-02 16:22:36 -07003404 validBuf[i] = true;
3405 numOfBuf++;
3406 } else {
3407 validBuf[i] = false;
3408 }
3409 }
3410
3411 struct v4l2_format v4l2_fmt;
3412 struct v4l2_pix_format pixfmt;
3413 unsigned int bpp;
3414 unsigned int planes;
3415
3416 memset(&v4l2_fmt, 0, sizeof(struct v4l2_format));
3417 memset(&pixfmt, 0, sizeof(pixfmt));
3418
3419 switch(mode) {
3420 case PREVIEW_MODE:
3421 case VIDEO_MODE:
3422 v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3423
3424 V4L2_PIX_2_YUV_INFO(colorFormat, &bpp, &planes);
3425
3426 v4l2_fmt.fmt.pix_mp.width = w;
3427 v4l2_fmt.fmt.pix_mp.height = h;
3428 v4l2_fmt.fmt.pix_mp.pixelformat = colorFormat;
3429 v4l2_fmt.fmt.pix_mp.num_planes = planes;
3430
3431 if (exynos_v4l2_s_fmt(fd, &v4l2_fmt) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003432 ALOGE("ERR(%s):exynos_v4l2_s_fmt() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003433 return false;
3434 }
3435 break;
3436 case PICTURE_MODE:
3437 v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3438
3439 pixfmt.width = w;
3440 pixfmt.height = h;
3441 pixfmt.pixelformat = colorFormat;
3442 if (pixfmt.pixelformat == V4L2_PIX_FMT_JPEG)
3443 pixfmt.colorspace = V4L2_COLORSPACE_JPEG;
3444
3445 v4l2_fmt.fmt.pix = pixfmt;
3446
3447 if (exynos_v4l2_s_fmt(fd, &v4l2_fmt) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003448 ALOGE("ERR(%s):exynos_v4l2_s_fmt() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003449 return false;
3450 }
3451 break;
3452 default:
3453 break;
3454 }
3455
3456 struct v4l2_requestbuffers req;
3457 req.count = numOfBuf;
3458 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07003459 req.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07003460
3461 if (exynos_v4l2_reqbufs(fd, &req) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003462 ALOGE("ERR(%s):exynos_v4l2_reqbufs(%d) fail", __func__, numOfBuf);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003463 return false;
3464 }
3465
3466 for (int i = 0; i < VIDEO_MAX_FRAME; i++) {
3467 if (validBuf[i] == true) {
3468
3469 struct v4l2_buffer v4l2_buf;
3470 struct v4l2_plane planes[VIDEO_MAX_PLANES];
3471
3472 v4l2_buf.m.planes = planes;
3473 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07003474 v4l2_buf.memory = V4L2_MEMORY_DMABUF;
Jiyoung Shin9426c422012-04-02 16:22:36 -07003475 v4l2_buf.index = buf[i].reserved.p;
3476 v4l2_buf.length = 0;
3477
3478 for (int j = 0; j < 3; j++) {
Rebecca Schultz Zavin471812b2012-05-15 16:49:56 -07003479 v4l2_buf.m.planes[j].m.fd = buf[i].fd.extFd[j];
Jiyoung Shin9426c422012-04-02 16:22:36 -07003480 v4l2_buf.m.planes[j].length = buf[i].size.extS[j];
3481
3482 if (buf[i].size.extS[j] != 0)
3483 v4l2_buf.length++;
3484 }
3485
3486 if (exynos_v4l2_qbuf(fd, &v4l2_buf) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003487 ALOGE("ERR(%s):exynos_v4l2_qbuf(%d) fail", __func__, i);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003488 return false;
3489 }
3490 }
3491 }
3492
3493 /*
3494 m_currentZoom = -1;
3495
3496 if (m_setZoom(fd, m_curCameraInfo->zoom, w, h) == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07003497 ALOGE("ERR(%s):m_setZoom(%d, %d) fail", __func__, mode, m_curCameraInfo->zoom);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003498 */
3499 return true;
3500}
3501
3502bool ExynosCamera::m_setZoom(int fd, int zoom, int w, int h)
3503{
3504 int ret = true;
3505
3506 if (m_currentZoom != zoom) {
3507 m_currentZoom = zoom;
3508
3509 int real_zoom = 0;
3510
3511 if (m_defaultCameraInfo->hwZoomSupported == true)
3512 real_zoom = 0; // just adjust ratio, not digital zoom.
3513 else
3514 real_zoom = zoom; // adjust ratio, digital zoom
3515
3516 ret = m_setCrop(fd, w, h, real_zoom);
3517 if (ret == false)
Dima Zavinf4979f52012-05-01 21:49:24 -07003518 ALOGE("ERR(%s):m_setCrop(%d, %d) fail", __func__, w, h);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003519 }
3520
3521 return ret;
3522}
3523
3524bool ExynosCamera::m_setCrop(int fd, int w, int h, int zoom)
3525{
3526 v4l2_cropcap cropcap;
3527 v4l2_crop crop;
3528 unsigned int crop_x = 0;
3529 unsigned int crop_y = 0;
3530 unsigned int crop_w = 0;
3531 unsigned int crop_h = 0;
3532
3533 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3534
3535 if (exynos_v4l2_cropcap(fd, &cropcap) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003536 ALOGE("ERR(%s):exynos_v4l2_cropcap() fail)", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003537 return false;
3538 }
3539
3540 m_getCropRect(cropcap.bounds.width, cropcap.bounds.height,
3541 w, h,
3542 &crop_x, &crop_y,
3543 &crop_w, &crop_h,
3544 zoom);
3545
3546 cropcap.defrect.left = crop_x;
3547 cropcap.defrect.top = crop_y;
3548 cropcap.defrect.width = crop_w;
3549 cropcap.defrect.height = crop_h;
3550 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3551 crop.c = cropcap.defrect;
3552
3553 if (exynos_v4l2_s_crop(fd, &crop) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003554 ALOGE("ERR(%s):exynos_v4l2_s_crop() fail(%d))", __func__, zoom);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003555 return false;
3556 }
3557
3558 /*
Dima Zavinf4979f52012-05-01 21:49:24 -07003559 ALOGD("## 1 w : %d", w);
3560 ALOGD("## 1 h : %d", h);
3561 ALOGD("## 1 zoom : %d", zoom);
3562 ALOGD("## 1 cropcap.bounds.w : %d", cropcap.bounds.width);
3563 ALOGD("## 1 cropcap.bounds.h : %d", cropcap.bounds.height);
3564 ALOGD("## 2 crop_x : %d", crop_x);
3565 ALOGD("## 2 crop_y : %d", crop_y);
3566 ALOGD("## 2 crop_w : %d", crop_w);
3567 ALOGD("## 2 crop_h : %d", crop_h);
3568 ALOGD("## 2 cropcap.defrect.left : %d", cropcap.defrect.left);
3569 ALOGD("## 2 cropcap.defrect.top : %d", cropcap.defrect.top);
3570 ALOGD("## 2 cropcap.defrect.width : %d", cropcap.defrect.width);
3571 ALOGD("## 2 cropcap.defrect.height: %d", cropcap.defrect.height);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003572 */
3573
3574 return true;
3575}
3576
3577bool ExynosCamera::m_getCropRect(unsigned int src_w, unsigned int src_h,
3578 unsigned int dst_w, unsigned int dst_h,
3579 unsigned int *crop_x, unsigned int *crop_y,
3580 unsigned int *crop_w, unsigned int *crop_h,
3581 int zoom)
3582{
3583 #define DEFAULT_ZOOM_RATIO (4) // 4x zoom
3584 #define DEFAULT_ZOOM_RATIO_SHIFT (2)
3585 int max_zoom = m_defaultCameraInfo->maxZoom;
3586
3587 *crop_w = src_w;
3588 *crop_h = src_h;
3589
3590 if ( src_w != dst_w
3591 || src_h != dst_h) {
3592 float src_ratio = 1.0f;
3593 float dst_ratio = 1.0f;
3594
3595 // ex : 1024 / 768
3596 src_ratio = (float)src_w / (float)src_h;
3597
3598 // ex : 352 / 288
3599 dst_ratio = (float)dst_w / (float)dst_h;
3600
3601 if (src_ratio != dst_ratio) {
3602 if (src_ratio <= dst_ratio) {
3603 // shrink h
3604 *crop_w = src_w;
3605 *crop_h = src_w / dst_ratio;
3606 } else { //(src_ratio > dst_ratio)
3607 // shrink w
3608 *crop_w = src_h * dst_ratio;
3609 *crop_h = src_h;
3610 }
3611 }
3612
3613 if (zoom != 0) {
3614 unsigned int zoom_w_step =
3615 (*crop_w - (*crop_w >> DEFAULT_ZOOM_RATIO_SHIFT)) / max_zoom;
3616
3617 *crop_w = *crop_w - (zoom_w_step * zoom);
3618
3619 unsigned int zoom_h_step =
3620 (*crop_h - (*crop_h >> DEFAULT_ZOOM_RATIO_SHIFT)) / max_zoom;
3621
3622 *crop_h = *crop_h - (zoom_h_step * zoom);
3623 }
3624 }
3625
3626 #define CAMERA_CROP_WIDTH_RESTRAIN_NUM (0x10) // 16
3627 unsigned int w_align = (*crop_w & (CAMERA_CROP_WIDTH_RESTRAIN_NUM - 1));
3628 if (w_align != 0) {
3629 if ( (CAMERA_CROP_WIDTH_RESTRAIN_NUM >> 1) <= w_align
3630 && *crop_w + (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align) <= dst_w) {
3631 *crop_w += (CAMERA_CROP_WIDTH_RESTRAIN_NUM - w_align);
3632 }
3633 else
3634 *crop_w -= w_align;
3635 }
3636
3637 #define CAMERA_CROP_HEIGHT_RESTRAIN_NUM (0x2) // 2
3638 unsigned int h_align = (*crop_h & (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - 1));
3639 if (h_align != 0) {
3640 if ( (CAMERA_CROP_HEIGHT_RESTRAIN_NUM >> 1) <= h_align
3641 && *crop_h + (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align) <= dst_h) {
3642 *crop_h += (CAMERA_CROP_HEIGHT_RESTRAIN_NUM - h_align);
3643 }
3644 else
3645 *crop_h -= h_align;
3646 }
3647
3648 *crop_x = (src_w - *crop_w) >> 1;
3649 *crop_y = (src_h - *crop_h) >> 1;
3650
3651 return true;
3652}
3653
3654void ExynosCamera::m_setExifFixedAttribute(void)
3655{
3656 char property[PROPERTY_VALUE_MAX];
3657
3658 //2 0th IFD TIFF Tags
3659 //3 Maker
3660 property_get("ro.product.brand", property, EXIF_DEF_MAKER);
3661 strncpy((char *)mExifInfo.maker, property,
3662 sizeof(mExifInfo.maker) - 1);
3663 mExifInfo.maker[sizeof(mExifInfo.maker) - 1] = '\0';
3664 //3 Model
3665 property_get("ro.product.model", property, EXIF_DEF_MODEL);
3666 strncpy((char *)mExifInfo.model, property,
3667 sizeof(mExifInfo.model) - 1);
3668 mExifInfo.model[sizeof(mExifInfo.model) - 1] = '\0';
3669 //3 Software
3670 property_get("ro.build.id", property, EXIF_DEF_SOFTWARE);
3671 strncpy((char *)mExifInfo.software, property,
3672 sizeof(mExifInfo.software) - 1);
3673 mExifInfo.software[sizeof(mExifInfo.software) - 1] = '\0';
3674
3675 //3 YCbCr Positioning
3676 mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING;
3677
3678 //2 0th IFD Exif Private Tags
3679 //3 F Number
3680 mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM;
3681 mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN;
3682 //3 Exposure Program
3683 mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM;
3684 //3 Exif Version
3685 memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version));
3686 //3 Aperture
3687 uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den);
3688 mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN;
3689 mExifInfo.aperture.den = EXIF_DEF_APEX_DEN;
3690 //3 Maximum lens aperture
3691 mExifInfo.max_aperture.num = mExifInfo.aperture.num;
3692 mExifInfo.max_aperture.den = mExifInfo.aperture.den;
3693 //3 Lens Focal Length
3694 mExifInfo.focal_length.num = m_defaultCameraInfo->focalLengthNum;
3695 mExifInfo.focal_length.den = m_defaultCameraInfo->focalLengthDen;
3696 //3 User Comments
3697 strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS);
3698 //3 Color Space information
3699 mExifInfo.color_space = EXIF_DEF_COLOR_SPACE;
3700 //3 Exposure Mode
3701 mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE;
3702
3703 //2 0th IFD GPS Info Tags
3704 unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 };
3705 memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version));
3706
3707 //2 1th IFD TIFF Tags
3708 mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION;
3709 mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM;
3710 mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN;
3711 mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM;
3712 mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN;
3713 mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT;
3714}
3715
3716void ExynosCamera::m_setExifChangedAttribute(exif_attribute_t *exifInfo, ExynosRect *rect)
3717{
3718 //2 0th IFD TIFF Tags
3719 //3 Width
3720 exifInfo->width = rect->w;
3721 //3 Height
3722 exifInfo->height = rect->h;
3723 //3 Orientation
3724 switch (m_curCameraInfo->rotation) {
3725 case 90:
3726 exifInfo->orientation = EXIF_ORIENTATION_90;
3727 break;
3728 case 180:
3729 exifInfo->orientation = EXIF_ORIENTATION_180;
3730 break;
3731 case 270:
3732 exifInfo->orientation = EXIF_ORIENTATION_270;
3733 break;
3734 case 0:
3735 default:
3736 exifInfo->orientation = EXIF_ORIENTATION_UP;
3737 break;
3738 }
3739 //3 Date time
3740 time_t rawtime;
3741 struct tm *timeinfo;
3742 time(&rawtime);
3743 timeinfo = localtime(&rawtime);
3744 strftime((char *)exifInfo->date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
3745
3746 //2 0th IFD Exif Private Tags
3747 //3 Exposure Time
3748 int shutterSpeed = 100;
3749 /* TBD - front camera needs to be fixed to support this g_ctrl,
3750 it current returns a negative err value, so avoid putting
3751 odd value into exif for now */
3752 if ( exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_EXIF_SHUTTERSPEED, &shutterSpeed) < 0
3753 || shutterSpeed < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003754 ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail, using 100", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003755 shutterSpeed = 100;
3756 }
3757
3758 exifInfo->exposure_time.num = 1;
3759 // x us -> 1/x s */
3760 exifInfo->exposure_time.den = (uint32_t)(1000000 / shutterSpeed);
3761
3762 //3 ISO Speed Rating
3763 int iso = m_curCameraInfo->iso;
3764
3765 /* TBD - front camera needs to be fixed to support this g_ctrl,
3766 it current returns a negative err value, so avoid putting
3767 odd value into exif for now */
3768 if ( exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_EXIF_ISO, &iso) < 0
3769 || iso < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07003770 ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail, using ISO_100", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003771 iso = ISO_100;
3772 }
3773
3774 switch (iso) {
3775 case ISO_50:
3776 exifInfo->iso_speed_rating = 50;
3777 break;
3778 case ISO_100:
3779 exifInfo->iso_speed_rating = 100;
3780 break;
3781 case ISO_200:
3782 exifInfo->iso_speed_rating = 200;
3783 break;
3784 case ISO_400:
3785 exifInfo->iso_speed_rating = 400;
3786 break;
3787 case ISO_800:
3788 exifInfo->iso_speed_rating = 800;
3789 break;
3790 case ISO_1600:
3791 exifInfo->iso_speed_rating = 1600;
3792 break;
3793 default:
3794 exifInfo->iso_speed_rating = 100;
3795 break;
3796 }
3797
3798 uint32_t av, tv, bv, sv, ev;
3799 av = APEX_FNUM_TO_APERTURE((double)exifInfo->fnumber.num / exifInfo->fnumber.den);
3800 tv = APEX_EXPOSURE_TO_SHUTTER((double)exifInfo->exposure_time.num / exifInfo->exposure_time.den);
3801 sv = APEX_ISO_TO_FILMSENSITIVITY(exifInfo->iso_speed_rating);
3802 bv = av + tv - sv;
3803 ev = av + tv;
Dima Zavinf4979f52012-05-01 21:49:24 -07003804 ALOGD("Shutter speed=%d us, iso=%d", shutterSpeed, exifInfo->iso_speed_rating);
3805 ALOGD("AV=%d, TV=%d, SV=%d", av, tv, sv);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003806
3807 //3 Shutter Speed
3808 exifInfo->shutter_speed.num = tv * EXIF_DEF_APEX_DEN;
3809 exifInfo->shutter_speed.den = EXIF_DEF_APEX_DEN;
3810 //3 Brightness
3811 exifInfo->brightness.num = bv*EXIF_DEF_APEX_DEN;
3812 exifInfo->brightness.den = EXIF_DEF_APEX_DEN;
3813 //3 Exposure Bias
3814 if (m_curCameraInfo->sceneMode == SCENE_MODE_BEACH ||
3815 m_curCameraInfo->sceneMode == SCENE_MODE_SNOW) {
3816 exifInfo->exposure_bias.num = EXIF_DEF_APEX_DEN;
3817 exifInfo->exposure_bias.den = EXIF_DEF_APEX_DEN;
3818 } else {
3819 exifInfo->exposure_bias.num = 0;
3820 exifInfo->exposure_bias.den = 0;
3821 }
3822 //3 Metering Mode
3823 switch (m_curCameraInfo->metering) {
3824 case METERING_MODE_CENTER:
3825 exifInfo->metering_mode = EXIF_METERING_CENTER;
3826 break;
3827 case METERING_MODE_MATRIX:
3828 exifInfo->metering_mode = EXIF_METERING_MULTISPOT;
3829 break;
3830 case METERING_MODE_SPOT:
3831 exifInfo->metering_mode = EXIF_METERING_SPOT;
3832 break;
3833 case METERING_MODE_AVERAGE:
3834 default:
3835 exifInfo->metering_mode = EXIF_METERING_AVERAGE;
3836 break;
3837 }
3838
3839 //3 Flash
3840 int flash = EXIF_DEF_FLASH;
3841 if ( m_curCameraInfo->flashMode == FLASH_MODE_OFF
3842 || exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_EXIF_FLASH, &flash) < 0
3843 || flash < 0)
3844 exifInfo->flash = EXIF_DEF_FLASH;
3845 else
3846 exifInfo->flash = flash;
3847
3848 //3 White Balance
3849 if (m_curCameraInfo->whiteBalance == WHITE_BALANCE_AUTO)
3850 exifInfo->white_balance = EXIF_WB_AUTO;
3851 else
3852 exifInfo->white_balance = EXIF_WB_MANUAL;
3853
3854 //3 Scene Capture Type
3855 switch (m_curCameraInfo->sceneMode) {
3856 case SCENE_MODE_PORTRAIT:
3857 exifInfo->scene_capture_type = EXIF_SCENE_PORTRAIT;
3858 break;
3859 case SCENE_MODE_LANDSCAPE:
3860 exifInfo->scene_capture_type = EXIF_SCENE_LANDSCAPE;
3861 break;
3862 case SCENE_MODE_NIGHT:
3863 exifInfo->scene_capture_type = EXIF_SCENE_NIGHT;
3864 break;
3865 default:
3866 exifInfo->scene_capture_type = EXIF_SCENE_STANDARD;
3867 break;
3868 }
3869
3870 //2 0th IFD GPS Info Tags
3871 if (m_curCameraInfo->gpsLatitude != 0 && m_curCameraInfo->gpsLongitude != 0) {
3872 if (m_curCameraInfo->gpsLatitude > 0)
3873 strcpy((char *)exifInfo->gps_latitude_ref, "N");
3874 else
3875 strcpy((char *)exifInfo->gps_latitude_ref, "S");
3876
3877 if (m_curCameraInfo->gpsLongitude > 0)
3878 strcpy((char *)exifInfo->gps_longitude_ref, "E");
3879 else
3880 strcpy((char *)exifInfo->gps_longitude_ref, "W");
3881
3882 if (m_curCameraInfo->gpsAltitude > 0)
3883 exifInfo->gps_altitude_ref = 0;
3884 else
3885 exifInfo->gps_altitude_ref = 1;
3886
3887 double latitude = fabs(m_curCameraInfo->gpsLatitude / 10000.0);
3888 double longitude = fabs(m_curCameraInfo->gpsLongitude / 10000.0);
3889 double altitude = fabs(m_curCameraInfo->gpsAltitude / 100.0);
3890
3891 exifInfo->gps_latitude[0].num = (uint32_t)latitude;
3892 exifInfo->gps_latitude[0].den = 1;
3893 exifInfo->gps_latitude[1].num = (uint32_t)((latitude - exifInfo->gps_latitude[0].num) * 60);
3894 exifInfo->gps_latitude[1].den = 1;
3895 exifInfo->gps_latitude[2].num = (uint32_t)((((latitude - exifInfo->gps_latitude[0].num) * 60)
3896 - exifInfo->gps_latitude[1].num) * 60);
3897 exifInfo->gps_latitude[2].den = 1;
3898
3899 exifInfo->gps_longitude[0].num = (uint32_t)longitude;
3900 exifInfo->gps_longitude[0].den = 1;
3901 exifInfo->gps_longitude[1].num = (uint32_t)((longitude - exifInfo->gps_longitude[0].num) * 60);
3902 exifInfo->gps_longitude[1].den = 1;
3903 exifInfo->gps_longitude[2].num = (uint32_t)((((longitude - exifInfo->gps_longitude[0].num) * 60)
3904 - exifInfo->gps_longitude[1].num) * 60);
3905 exifInfo->gps_longitude[2].den = 1;
3906
3907 exifInfo->gps_altitude.num = (uint32_t)altitude;
3908 exifInfo->gps_altitude.den = 1;
3909
3910 struct tm tm_data;
3911 gmtime_r(&m_curCameraInfo->gpsTimestamp, &tm_data);
3912 exifInfo->gps_timestamp[0].num = tm_data.tm_hour;
3913 exifInfo->gps_timestamp[0].den = 1;
3914 exifInfo->gps_timestamp[1].num = tm_data.tm_min;
3915 exifInfo->gps_timestamp[1].den = 1;
3916 exifInfo->gps_timestamp[2].num = tm_data.tm_sec;
3917 exifInfo->gps_timestamp[2].den = 1;
3918 snprintf((char*)exifInfo->gps_datestamp, sizeof(exifInfo->gps_datestamp),
3919 "%04d:%02d:%02d", tm_data.tm_year + 1900, tm_data.tm_mon + 1, tm_data.tm_mday);
3920
3921 exifInfo->enableGps = true;
3922 } else {
3923 exifInfo->enableGps = false;
3924 }
3925
3926 //2 1th IFD TIFF Tags
3927 exifInfo->widthThumb = m_curCameraInfo->thumbnailW;
3928 exifInfo->heightThumb = m_curCameraInfo->thumbnailH;
3929}
3930
3931void ExynosCamera::m_secRect2SecRect2(ExynosRect *rect, ExynosRect2 *rect2)
3932{
3933 rect2->x1 = rect->x;
3934 rect2->y1 = rect->y;
3935 rect2->x2 = rect->x + rect->w;
3936 rect2->y2 = rect->y + rect->h;
3937}
3938
3939void ExynosCamera::m_secRect22SecRect(ExynosRect2 *rect2, ExynosRect *rect)
3940{
3941 rect->x = rect2->x1;
3942 rect->y = rect2->y1;
3943 rect->w = rect2->x2 - rect2->x1;
3944 rect->h = rect2->y2 - rect2->y1;
3945}
3946
3947void ExynosCamera::m_printFormat(int colorFormat, const char *arg)
3948{
3949 switch (colorFormat) {
3950 case V4L2_PIX_FMT_YUV420:
Dima Zavinf4979f52012-05-01 21:49:24 -07003951 ALOGV("DEBUG(%s):V4L2_PIX_FMT_YUV420", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003952 break;
3953 case V4L2_PIX_FMT_YVU420:
Dima Zavinf4979f52012-05-01 21:49:24 -07003954 ALOGV("DEBUG(%s):V4L2_PIX_FMT_YVU420", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003955 break;
3956 case V4L2_PIX_FMT_YVU420M:
Dima Zavinf4979f52012-05-01 21:49:24 -07003957 ALOGV("DEBUG(%s):V4L2_PIX_FMT_YVU420M", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003958 break;
3959 case V4L2_PIX_FMT_NV12M:
Dima Zavinf4979f52012-05-01 21:49:24 -07003960 ALOGV("DEBUG(%s):V4L2_PIX_FMT_NV12M", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003961 break;
3962 case V4L2_PIX_FMT_NV12:
Dima Zavinf4979f52012-05-01 21:49:24 -07003963 ALOGV("DEBUG(%s):V4L2_PIX_FMT_NV12", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003964 break;
3965 case V4L2_PIX_FMT_NV12T:
Dima Zavinf4979f52012-05-01 21:49:24 -07003966 ALOGV("DEBUG(%s):V4L2_PIX_FMT_NV12T", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003967 break;
3968 case V4L2_PIX_FMT_NV21:
Dima Zavinf4979f52012-05-01 21:49:24 -07003969 ALOGV("DEBUG(%s):V4L2_PIX_FMT_NV21", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003970 break;
3971 case V4L2_PIX_FMT_YUV422P:
Dima Zavinf4979f52012-05-01 21:49:24 -07003972 ALOGV("DEBUG(%s):V4L2_PIX_FMT_YUV422PP", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003973 break;
3974 case V4L2_PIX_FMT_YUYV:
Dima Zavinf4979f52012-05-01 21:49:24 -07003975 ALOGV("DEBUG(%s):V4L2_PIX_FMT_YUYV", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003976 break;
3977 case V4L2_PIX_FMT_UYVY:
Dima Zavinf4979f52012-05-01 21:49:24 -07003978 ALOGV("DEBUG(%s):V4L2_PIX_FMT_UYVYI", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003979 break;
3980 case V4L2_PIX_FMT_RGB565:
Dima Zavinf4979f52012-05-01 21:49:24 -07003981 ALOGV("DEBUG(%s):V4L2_PIX_FMT_RGB565", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003982 break;
3983 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07003984 ALOGV("DEBUG(%s):Unknown Format", arg);
Jiyoung Shin9426c422012-04-02 16:22:36 -07003985 break;
3986 }
3987}
3988
3989///////////////////////////////////////////////////
3990// Additional API.
3991///////////////////////////////////////////////////
3992
3993bool ExynosCamera::setAngle(int angle)
3994{
3995 if (m_curCameraInfo->angle != angle) {
3996 switch (angle) {
3997 case -360:
3998 case 0:
3999 case 360:
4000 m_curCameraInfo->angle = 0;
4001 break;
4002
4003 case -270:
4004 case 90:
4005 m_curCameraInfo->angle = 90;
4006 break;
4007
4008 case -180:
4009 case 180:
4010 m_curCameraInfo->angle = 180;
4011 break;
4012
4013 case -90:
4014 case 270:
4015 m_curCameraInfo->angle = 270;
4016 break;
4017
4018 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07004019 ALOGE("ERR(%s):Invalid angle(%d)", __func__, angle);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004020 return false;
4021 }
4022
4023 if (m_flagCreate == true) {
4024 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_ROTATION, angle) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004025 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004026 return false;
4027 }
4028 }
4029 }
4030
4031 return true;
4032}
4033
4034int ExynosCamera::getAngle(void)
4035{
4036 return m_curCameraInfo->angle;
4037}
4038
4039bool ExynosCamera::setISO(int iso)
4040{
4041 int internalValue = -1;
4042
4043 switch (iso) {
4044 case 50:
4045 internalValue = ISO_50;
4046 break;
4047 case 100:
4048 internalValue = ISO_100;
4049 break;
4050 case 200:
4051 internalValue = ISO_200;
4052 break;
4053 case 400:
4054 internalValue = ISO_400;
4055 break;
4056 case 800:
4057 internalValue = ISO_800;
4058 break;
4059 case 1600:
4060 internalValue = ISO_1600;
4061 break;
4062 case 0:
4063 default:
4064 internalValue = ISO_AUTO;
4065 break;
4066 }
4067
4068 if (internalValue < ISO_AUTO || ISO_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004069 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004070 return false;
4071 }
4072
4073 if (m_curCameraInfo->iso != iso) {
4074 m_curCameraInfo->iso = iso;
4075 if (m_flagCreate == true) {
4076 if (m_internalISP == true) {
4077 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_ISO, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004078 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004079 return false;
4080 }
4081 } else {
4082 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_ISO, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004083 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004084 return false;
4085 }
4086 }
4087 }
4088 }
4089
4090 return true;
4091}
4092
4093int ExynosCamera::getISO(void)
4094{
4095 return m_curCameraInfo->iso;
4096}
4097
4098bool ExynosCamera::setContrast(int value)
4099{
4100 int internalValue = -1;
4101
4102 switch (value) {
4103 case CONTRAST_AUTO:
4104 if (m_internalISP == true)
4105 internalValue = ::IS_CONTRAST_AUTO;
4106 else
Dima Zavinf4979f52012-05-01 21:49:24 -07004107 ALOGW("WARN(%s):Invalid contrast value (%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004108 return true;
4109 break;
4110 case CONTRAST_MINUS_2:
4111 if (m_internalISP == true)
4112 internalValue = ::IS_CONTRAST_MINUS_2;
4113 else
4114 internalValue = ::CONTRAST_MINUS_2;
4115 break;
4116 case CONTRAST_MINUS_1:
4117 if (m_internalISP == true)
4118 internalValue = ::IS_CONTRAST_MINUS_1;
4119 else
4120 internalValue = ::CONTRAST_MINUS_1;
4121 break;
4122 case CONTRAST_DEFAULT:
4123 if (m_internalISP == true)
4124 internalValue = ::IS_CONTRAST_DEFAULT;
4125 else
4126 internalValue = ::CONTRAST_DEFAULT;
4127 break;
4128 case CONTRAST_PLUS_1:
4129 if (m_internalISP == true)
4130 internalValue = ::IS_CONTRAST_PLUS_1;
4131 else
4132 internalValue = ::CONTRAST_PLUS_1;
4133 break;
4134 case CONTRAST_PLUS_2:
4135 if (m_internalISP == true)
4136 internalValue = ::IS_CONTRAST_PLUS_2;
4137 else
4138 internalValue = ::CONTRAST_PLUS_2;
4139 break;
4140 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07004141 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004142 return false;
4143 break;
4144 }
4145
4146 if (m_internalISP == true) {
4147 if (internalValue < ::IS_CONTRAST_AUTO || ::IS_CONTRAST_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004148 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004149 return false;
4150 }
4151 } else {
4152 if (internalValue < ::CONTRAST_MINUS_2 || ::CONTRAST_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004153 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004154 return false;
4155 }
4156 }
4157
4158 if (m_curCameraInfo->contrast != value) {
4159 m_curCameraInfo->contrast = value;
4160 if (m_flagCreate == true) {
4161 if (m_internalISP == true) {
4162 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_CONTRAST, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004163 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004164 return false;
4165 }
4166 } else {
4167 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_CONTRAST, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004168 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004169 return false;
4170 }
4171 }
4172 }
4173 }
4174
4175 return true;
4176}
4177
4178int ExynosCamera::getContrast(void)
4179{
4180 return m_curCameraInfo->contrast;
4181}
4182
4183bool ExynosCamera::setSaturation(int saturation)
4184{
4185 int internalValue = saturation + SATURATION_DEFAULT;
4186 if (internalValue < SATURATION_MINUS_2 || SATURATION_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004187 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004188 return false;
4189 }
4190
4191 if (m_curCameraInfo->saturation != saturation) {
4192 m_curCameraInfo->saturation = saturation;
4193 if (m_flagCreate == true) {
4194 if (m_internalISP == true) {
4195 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_SATURATION, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004196 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004197 return false;
4198 }
4199 } else {
4200 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SATURATION, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004201 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004202 return false;
4203 }
4204 }
4205 }
4206 }
4207
4208 return true;
4209}
4210
4211int ExynosCamera::getSaturation(void)
4212{
4213 return m_curCameraInfo->saturation;
4214}
4215
4216bool ExynosCamera::setSharpness(int sharpness)
4217{
4218 int internalValue = sharpness + SHARPNESS_DEFAULT;
4219 if (internalValue < SHARPNESS_MINUS_2 || SHARPNESS_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004220 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004221 return false;
4222 }
4223
4224 if (m_curCameraInfo->sharpness != sharpness) {
4225 m_curCameraInfo->sharpness = sharpness;
4226 if (m_flagCreate == true) {
4227 if (m_internalISP == true) {
4228 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_SHARPNESS, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004229 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004230 return false;
4231 }
4232 } else {
4233 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SHARPNESS, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004234 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004235 return false;
4236 }
4237 }
4238 }
4239 }
4240
4241 return true;
4242}
4243
4244int ExynosCamera::getSharpness(void)
4245{
4246 return m_curCameraInfo->sharpness;
4247}
4248
4249bool ExynosCamera::setHue(int hue)
4250{
4251 int internalValue = hue;
4252
4253 if (m_internalISP == true) {
4254 internalValue += IS_HUE_DEFAULT;
4255 if (internalValue < IS_HUE_MINUS_2 || IS_HUE_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004256 ALOGE("ERR(%s):Invalid hue (%d)", __func__, hue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004257 return false;
4258 }
4259 } else {
Dima Zavinf4979f52012-05-01 21:49:24 -07004260 ALOGV("WARN(%s):Not supported hue setting", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004261 return true;
4262 }
4263
4264 if (m_curCameraInfo->hue != hue) {
4265 m_curCameraInfo->hue = hue;
4266 if (m_flagCreate == true) {
4267 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_HUE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004268 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004269 return false;
4270 }
4271 }
4272 }
4273
4274 return true;
4275}
4276
4277int ExynosCamera::getHue(void)
4278{
4279 return m_curCameraInfo->hue;
4280}
4281
4282bool ExynosCamera::setWDR(bool toggle)
4283{
4284 int internalWdr;
4285
4286 if (toggle == true) {
4287 if (m_internalISP == true)
4288 internalWdr = IS_DRC_BYPASS_ENABLE;
4289 else
4290 internalWdr = IS_DRC_BYPASS_DISABLE;
4291 } else {
4292 if (m_internalISP == true)
4293 internalWdr = WDR_ON;
4294 else
4295 internalWdr = WDR_OFF;
4296 }
4297
4298 if (m_curCameraInfo->wdr != toggle) {
4299 m_curCameraInfo->wdr = toggle;
4300 if (m_flagCreate == true) {
4301 if (m_internalISP == true) {
4302 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_SET_DRC, internalWdr) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004303 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004304 return false;
4305 }
4306 } else {
4307 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_WDR, internalWdr) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004308 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004309 return false;
4310 }
4311 }
4312 }
4313 }
4314
4315 return true;
4316}
4317
4318bool ExynosCamera::getWDR(void)
4319{
4320 return m_curCameraInfo->wdr;
4321}
4322
4323bool ExynosCamera::setAntiShake(bool toggle)
4324{
4325 int internalValue = ANTI_SHAKE_OFF;
4326
4327 if (toggle == true)
4328 internalValue = ANTI_SHAKE_STILL_ON;
4329
4330 if (m_curCameraInfo->antiShake != toggle) {
4331 m_curCameraInfo->antiShake = toggle;
4332 if (m_flagCreate == true) {
4333 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_ANTI_SHAKE, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004334 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004335 return false;
4336 }
4337 }
4338 }
4339
4340 return true;
4341}
4342
4343bool ExynosCamera::getAntiShake(void)
4344{
4345 return m_curCameraInfo->antiShake;
4346}
4347
4348bool ExynosCamera::setMeteringMode(int value)
4349{
4350 int internalValue = -1;
4351
4352 switch (value) {
4353 case METERING_MODE_AVERAGE:
4354 if (m_internalISP == true)
4355 internalValue = IS_METERING_AVERAGE;
4356 else
4357 internalValue = METERING_MATRIX;
4358 break;
4359 case METERING_MODE_MATRIX:
4360 if (m_internalISP == true)
4361 internalValue = IS_METERING_MATRIX;
4362 else
4363 internalValue = METERING_MATRIX;
4364 break;
4365 case METERING_MODE_CENTER:
4366 if (m_internalISP == true)
4367 internalValue = IS_METERING_CENTER;
4368 else
4369 internalValue = METERING_CENTER;
4370 break;
4371 case METERING_MODE_SPOT:
4372 if (m_internalISP == true)
4373 internalValue = IS_METERING_SPOT;
4374 else
4375 internalValue = METERING_SPOT;
4376 break;
4377 default:
Dima Zavinf4979f52012-05-01 21:49:24 -07004378 ALOGE("ERR(%s):Unsupported value(%d)", __func__, value);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004379 return false;
4380 break;
4381 }
4382
4383 if (m_internalISP == true) {
4384 if (internalValue < IS_METERING_AVERAGE || IS_METERING_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004385 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004386 return false;
4387 }
4388 } else {
4389 if (internalValue <= METERING_BASE || METERING_MAX <= internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004390 ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004391 return false;
4392 }
4393 }
4394
4395 if (m_curCameraInfo->metering != value) {
4396 m_curCameraInfo->metering = value;
4397 if (m_flagCreate == true) {
4398 if (m_internalISP == true) {
4399 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_METERING, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004400 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004401 return false;
4402 }
4403 } else {
4404 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_METERING, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004405 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004406 return false;
4407 }
4408 }
4409 }
4410 }
4411
4412 return true;
4413}
4414
4415int ExynosCamera::getMeteringMode(void)
4416{
4417 return m_curCameraInfo->metering;
4418}
4419
4420bool ExynosCamera::setObjectTracking(bool toggle)
4421{
4422 m_curCameraInfo->objectTracking = toggle;
4423 return true;
4424}
4425
4426bool ExynosCamera::getObjectTracking(void)
4427{
4428 return m_curCameraInfo->objectTracking;
4429}
4430
4431bool ExynosCamera::setObjectTrackingStart(bool toggle)
4432{
4433 if (m_curCameraInfo->objectTrackingStart != toggle) {
4434 m_curCameraInfo->objectTrackingStart = toggle;
4435
4436 int startStop = (toggle == true) ? 1 : 0;
4437 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP, startStop) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004438 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004439 return false;
4440 }
4441 }
4442
4443 return true;
4444}
4445
4446int ExynosCamera::getObjectTrackingStatus(void)
4447{
4448 int ret = 0;
4449
4450 if (exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJ_TRACKING_STATUS, &ret) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004451 ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004452 return -1;
4453 }
4454 return ret;
4455}
4456
4457bool ExynosCamera::setObjectPosition(int x, int y)
4458{
4459 if (m_curCameraInfo->previewW == 640)
4460 x = x - 80;
4461
4462 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_OBJECT_POSITION_X, x) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004463 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004464 return false;
4465 }
4466
4467 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_OBJECT_POSITION_Y, y) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004468 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004469 return false;
4470 }
4471
4472 return true;
4473}
4474
4475bool ExynosCamera::setTouchAFStart(bool toggle)
4476{
4477 if (m_curCameraInfo->touchAfStart != toggle) {
4478 m_curCameraInfo->touchAfStart = toggle;
4479 int startStop = (toggle == true) ? 1 : 0;
4480
4481 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_TOUCH_AF_START_STOP, startStop) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004482 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004483 return false;
4484 }
4485 }
4486
4487 return true;
4488}
4489
4490bool ExynosCamera::setSmartAuto(bool toggle)
4491{
4492 if (m_curCameraInfo->smartAuto != toggle) {
4493 m_curCameraInfo->smartAuto = toggle;
4494
4495 int smartAuto = (toggle == true) ? SMART_AUTO_ON : SMART_AUTO_OFF;
4496
4497 if (m_flagCreate == true) {
4498 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SMART_AUTO, smartAuto) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004499 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004500 return false;
4501 }
4502 }
4503 }
4504
4505 return true;
4506}
4507
4508bool ExynosCamera::getSmartAuto(void)
4509{
4510 return m_curCameraInfo->smartAuto;
4511}
4512
4513int ExynosCamera::getSmartAutoStatus(void)
4514{
4515 int autoscene_status = -1;
4516
4517 if (m_curCameraInfo->smartAuto == true) {
4518 if (exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SMART_AUTO_STATUS, &autoscene_status) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004519 ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004520 return -1;
4521 }
4522
4523 if ((autoscene_status < SMART_AUTO_STATUS_AUTO) || (autoscene_status > SMART_AUTO_STATUS_MAX)) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004524 ALOGE("ERR(%s):Invalid getSmartAutoStatus (%d)", __func__, autoscene_status);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004525 return -1;
4526 }
4527 }
4528 return autoscene_status;
4529}
4530
4531bool ExynosCamera::setBeautyShot(bool toggle)
4532{
4533 if (m_curCameraInfo->beautyShot != toggle) {
4534 m_curCameraInfo->beautyShot = toggle;
4535 int beautyShot = (toggle == true) ? BEAUTY_SHOT_ON : BEAUTY_SHOT_OFF;
4536
4537 if (m_flagCreate == true) {
4538 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_BEAUTY_SHOT, beautyShot) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004539 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004540 return false;
4541 }
4542 }
4543 }
4544
4545 return true;
4546}
4547
4548bool ExynosCamera::getBeautyShot(void)
4549{
4550 return m_curCameraInfo->beautyShot;
4551}
4552
4553bool ExynosCamera::setTopDownMirror(void)
4554{
4555 if (m_previewDev->fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004556 ALOGE("ERR(%s):Camera was closed", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004557 return false;
4558 }
4559
4560 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_VFLIP, 1) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004561 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004562 return false;
4563 }
4564
4565 return true;
4566}
4567
4568bool ExynosCamera::setLRMirror(void)
4569{
4570 if (m_previewDev->fd <= 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004571 ALOGE("ERR(%s):Camera was closed", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004572 return false;
4573 }
4574
4575 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_HFLIP, 1) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004576 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004577 return false;
4578 }
4579
4580 return true;
4581}
4582
4583bool ExynosCamera::setBrightness(int brightness)
4584{
4585 int internalValue = brightness;
4586
4587 if (m_internalISP == true) {
4588 internalValue += IS_BRIGHTNESS_DEFAULT;
4589 if (internalValue < IS_BRIGHTNESS_MINUS_2 || IS_BRIGHTNESS_PLUS_2 < internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004590 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004591 return false;
4592 }
4593 } else {
4594 internalValue += EV_DEFAULT;
4595 if (internalValue < EV_MINUS_4 || EV_PLUS_4 < internalValue) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004596 ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004597 return false;
4598 }
4599 }
4600
4601 if (m_curCameraInfo->brightness != brightness) {
4602 m_curCameraInfo->brightness = brightness;
4603 if (m_flagCreate == true) {
4604 if (m_internalISP == true) {
4605 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_BRIGHTNESS, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004606 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004607 return false;
4608 }
4609 } else {
4610 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_BRIGHTNESS, internalValue) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004611 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004612 return false;
4613 }
4614 }
4615 }
4616 }
4617
4618 return true;
4619}
4620
4621int ExynosCamera::getBrightness(void)
4622{
4623 return m_curCameraInfo->brightness;
4624}
4625
4626bool ExynosCamera::setGamma(bool toggle)
4627{
4628 if (m_curCameraInfo->gamma != toggle) {
4629 m_curCameraInfo->gamma = toggle;
4630
4631 int gamma = (toggle == true) ? GAMMA_ON : GAMMA_OFF;
4632
4633 if (m_flagCreate == true) {
4634 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_GAMMA, gamma) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004635 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004636 return false;
4637 }
4638 }
4639 }
4640
4641 return true;
4642}
4643
4644bool ExynosCamera::getGamma(void)
4645{
4646 return m_curCameraInfo->gamma;
4647}
4648
4649bool ExynosCamera::setODC(bool toggle)
4650{
4651 if (m_previewDev->flagStart == true) {
4652 if (m_curCameraInfo->odc != toggle) {
4653 m_curCameraInfo->odc = toggle;
4654
4655 int odc = (toggle == true) ? CAMERA_ODC_ON : CAMERA_ODC_OFF;
4656
4657 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_ODC, odc) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004658 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004659 return false;
4660 }
4661 }
4662 }
4663
4664 return true;
4665}
4666
4667bool ExynosCamera::getODC(void)
4668{
4669 return m_curCameraInfo->odc;
4670}
4671
4672bool ExynosCamera::setSlowAE(bool toggle)
4673{
4674 if (m_curCameraInfo->slowAE != toggle) {
4675 m_curCameraInfo->slowAE = toggle;
4676
4677 int slow_ae = (toggle == true) ? SLOW_AE_ON : SLOW_AE_OFF;
4678
4679 if (m_flagCreate == true) {
4680 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_SLOW_AE, slow_ae) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004681 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004682 return false;
4683 }
4684 }
4685 }
4686
4687 return true;
4688}
4689
4690bool ExynosCamera::getSlowAE(void)
4691{
4692 return m_curCameraInfo->slowAE;
4693}
4694
4695bool ExynosCamera::setShotMode(int shotMode)
4696{
4697 if (shotMode < SHOT_MODE_SINGLE || SHOT_MODE_SELF < shotMode) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004698 ALOGE("ERR(%s):Invalid shotMode (%d)", __func__, shotMode);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004699 return false;
4700 }
4701
4702 if (m_curCameraInfo->shotMode != shotMode) {
4703 m_curCameraInfo->shotMode = shotMode;
4704
4705 if (m_flagCreate == true) {
4706 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL, shotMode) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004707 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004708 return false;
4709 }
4710 }
4711 }
4712
4713 return true;
4714}
4715
4716int ExynosCamera::getShotMode(void)
4717{
4718 return m_curCameraInfo->shotMode;
4719}
4720
4721bool ExynosCamera::set3DNR(bool toggle)
4722{
4723 if (m_previewDev->flagStart == true) {
4724 if (m_curCameraInfo->tdnr != toggle) {
4725 m_curCameraInfo->tdnr = toggle;
4726
4727 int tdnr = (toggle == true) ? CAMERA_3DNR_ON : CAMERA_3DNR_OFF;
4728
4729 if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_3DNR, tdnr) < 0) {
Dima Zavinf4979f52012-05-01 21:49:24 -07004730 ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__);
Jiyoung Shin9426c422012-04-02 16:22:36 -07004731 return false;
4732 }
4733 }
4734 }
4735
4736 return true;
4737}
4738
4739bool ExynosCamera::get3DNR(void)
4740{
4741 return m_curCameraInfo->tdnr;
4742}
4743
4744}; // namespace android