| /* |
| * Copyright 2008, The Android Open Source Project |
| * Copyright 2010, Samsung Electronics Co. LTD |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed toggle an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /*! |
| * \file ExynosCamera.cpp |
| * \brief source file for CAMERA HAL MODULE |
| * \author thun.hwang(thun.hwang@samsung.com) |
| * \date 2010/06/03 |
| * |
| * <b>Revision History: </b> |
| * - 2011/12/31 : thun.hwang(thun.hwang@samsung.com) \n |
| * Initial version |
| * |
| * - 2012/01/18 : Sangwoo, Park(sw5771.park@samsung.com) \n |
| * Adjust Doxygen Document |
| * |
| * - 2012/02/01 : Sangwoo, Park(sw5771.park@samsung.com) \n |
| * Adjust libv4l2 |
| * Adjust struct ExynosCameraInfo |
| * External ISP feature |
| * |
| * - 2012/03/14 : sangwoo.park(sw5771.park@samsung.com) \n |
| * Change file, class name to ExynosXXX. |
| */ |
| |
| /** |
| * @page ExynosCamera |
| * |
| * @section Introduction |
| * ExynosCamera is for camera preview,takePicture and recording. |
| * (Currently libseccamera is included in Android Camera HAL(libcamera.so). |
| * |
| * @section Copyright |
| * Copyright (c) 2008-2011 Samsung Electronics Co., Ltd.All rights reserved. \n |
| * Proprietary and Confidential |
| * |
| * @image html samsung.png |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "ExynosCamera" |
| |
| /* FIXME: This define will be removed when functions are stable */ |
| //#define USE_DIS |
| //#define USE_3DNR |
| //#define USE_ODC |
| |
| #include <utils/Log.h> |
| |
| #include "ExynosCamera.h" |
| #include "exynos_format.h" |
| |
| using namespace android; |
| |
| namespace android { |
| |
| ExynosCameraInfo::ExynosCameraInfo() |
| { |
| previewW = 2560; |
| previewH = 1920; |
| previewColorFormat = V4L2_PIX_FMT_NV21; |
| videoW = 1920; |
| videoH = 1080; |
| prefVideoPreviewW = 640; |
| prefVideoPreviewH = 360; |
| videoColorFormat = V4L2_PIX_FMT_NV12M; |
| pictureW = 2560; |
| pictureH = 1920; |
| pictureColorFormat = V4L2_PIX_FMT_YUYV; |
| thumbnailW = 320; |
| thumbnailH = 240; |
| |
| antiBandingList = |
| ExynosCamera::ANTIBANDING_OFF |
| | ExynosCamera::ANTIBANDING_50HZ |
| | ExynosCamera::ANTIBANDING_60HZ |
| | ExynosCamera::ANTIBANDING_OFF; |
| antiBanding = ExynosCamera::ANTIBANDING_OFF; |
| |
| effectList = |
| ExynosCamera::EFFECT_NONE |
| | ExynosCamera::EFFECT_MONO |
| | ExynosCamera::EFFECT_NEGATIVE |
| | ExynosCamera::EFFECT_SOLARIZE |
| | ExynosCamera::EFFECT_SEPIA |
| | ExynosCamera::EFFECT_POSTERIZE |
| | ExynosCamera::EFFECT_WHITEBOARD |
| | ExynosCamera::EFFECT_BLACKBOARD |
| | ExynosCamera::EFFECT_AQUA; |
| effect = ExynosCamera::EFFECT_NONE; |
| |
| flashModeList = |
| ExynosCamera::FLASH_MODE_OFF |
| | ExynosCamera::FLASH_MODE_AUTO |
| | ExynosCamera::FLASH_MODE_ON |
| | ExynosCamera::FLASH_MODE_RED_EYE |
| | ExynosCamera::FLASH_MODE_TORCH; |
| flashMode = ExynosCamera::FLASH_MODE_OFF; |
| |
| focusModeList = |
| ExynosCamera::FOCUS_MODE_AUTO |
| | ExynosCamera::FOCUS_MODE_INFINITY |
| | ExynosCamera::FOCUS_MODE_MACRO |
| | ExynosCamera::FOCUS_MODE_FIXED |
| | ExynosCamera::FOCUS_MODE_EDOF |
| | ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO |
| | ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE |
| | ExynosCamera::FOCUS_MODE_TOUCH; |
| focusMode = ExynosCamera::FOCUS_MODE_AUTO; |
| |
| sceneModeList = |
| ExynosCamera::SCENE_MODE_AUTO |
| | ExynosCamera::SCENE_MODE_ACTION |
| | ExynosCamera::SCENE_MODE_PORTRAIT |
| | ExynosCamera::SCENE_MODE_LANDSCAPE |
| | ExynosCamera::SCENE_MODE_NIGHT |
| | ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT |
| | ExynosCamera::SCENE_MODE_THEATRE |
| | ExynosCamera::SCENE_MODE_BEACH |
| | ExynosCamera::SCENE_MODE_SNOW |
| | ExynosCamera::SCENE_MODE_SUNSET |
| | ExynosCamera::SCENE_MODE_STEADYPHOTO |
| | ExynosCamera::SCENE_MODE_FIREWORKS |
| | ExynosCamera::SCENE_MODE_SPORTS |
| | ExynosCamera::SCENE_MODE_PARTY |
| | ExynosCamera::SCENE_MODE_CANDLELIGHT; |
| sceneMode = ExynosCamera::SCENE_MODE_AUTO; |
| |
| whiteBalanceList = |
| ExynosCamera::WHITE_BALANCE_AUTO |
| | ExynosCamera::WHITE_BALANCE_INCANDESCENT |
| | ExynosCamera::WHITE_BALANCE_FLUORESCENT |
| | ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT |
| | ExynosCamera::WHITE_BALANCE_DAYLIGHT |
| | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT |
| | ExynosCamera::WHITE_BALANCE_TWILIGHT |
| | ExynosCamera::WHITE_BALANCE_SHADE; |
| whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO; |
| |
| autoWhiteBalanceLockSupported = false; |
| autoWhiteBalanceLock = false; |
| |
| rotation = 0; |
| minExposure = -2; |
| maxExposure = 2; |
| exposure = 0; |
| |
| autoExposureLockSupported = false; |
| autoExposureLock = false; |
| |
| fps = 30; |
| focalLengthNum = 9; |
| focalLengthDen = 10; |
| supportVideoStabilization = false; |
| applyVideoStabilization = false; |
| videoStabilization = false; |
| maxNumMeteringAreas = 0; |
| maxNumDetectedFaces = 0; |
| maxNumFocusAreas = 0; |
| maxZoom = ZOOM_LEVEL_MAX; |
| hwZoomSupported = false; |
| zoom = 0; |
| gpsAltitude = 0; |
| gpsLatitude = 0; |
| gpsLongitude = 0; |
| gpsTimestamp = 0; |
| |
| // Additional API default Value. |
| angle = 0; |
| antiShake = false; |
| beautyShot = false; |
| brightness = 0; |
| contrast = ExynosCamera::CONTRAST_DEFAULT; |
| gamma = false; |
| hue = 2; // 2 is default; |
| iso = 0; |
| metering = ExynosCamera::METERING_MODE_CENTER; |
| objectTracking = false; |
| objectTrackingStart = false; |
| saturation = 0; |
| sharpness = 0; |
| shotMode = ExynosCamera::SHOT_MODE_SINGLE; |
| slowAE = false; |
| smartAuto = false; |
| touchAfStart = false; |
| wdr = false; |
| tdnr = false; |
| odc = false; |
| } |
| |
| ExynosCameraInfoM5M0::ExynosCameraInfoM5M0() |
| { |
| previewW = 1280; |
| previewH = 720; |
| previewColorFormat = V4L2_PIX_FMT_YVU420M; |
| videoW = 1280; |
| videoH = 720; |
| prefVideoPreviewW = 640; |
| prefVideoPreviewH = 360; |
| videoColorFormat = V4L2_PIX_FMT_NV12M; |
| pictureW = 1280; |
| pictureH = 720; |
| pictureColorFormat = V4L2_PIX_FMT_YUYV; |
| thumbnailW = 320; |
| thumbnailH = 240; |
| |
| antiBandingList = ExynosCamera::ANTIBANDING_OFF; |
| antiBanding = ExynosCamera::ANTIBANDING_OFF; |
| |
| effectList = |
| ExynosCamera::EFFECT_NONE |
| | ExynosCamera::EFFECT_MONO |
| | ExynosCamera::EFFECT_NEGATIVE |
| //| ExynosCamera::EFFECT_SOLARIZE |
| | ExynosCamera::EFFECT_SEPIA |
| //| ExynosCamera::EFFECT_POSTERIZE |
| //| ExynosCamera::EFFECT_WHITEBOARD |
| //| ExynosCamera::EFFECT_BLACKBOARD |
| | ExynosCamera::EFFECT_AQUA; |
| effect = ExynosCamera::EFFECT_NONE; |
| |
| flashModeList = |
| ExynosCamera::FLASH_MODE_OFF |
| | ExynosCamera::FLASH_MODE_AUTO |
| | ExynosCamera::FLASH_MODE_ON |
| | ExynosCamera::FLASH_MODE_RED_EYE |
| | ExynosCamera::FLASH_MODE_TORCH; |
| flashMode = ExynosCamera::FLASH_MODE_OFF; |
| |
| focusModeList = |
| ExynosCamera::FOCUS_MODE_AUTO |
| | ExynosCamera::FOCUS_MODE_INFINITY |
| | ExynosCamera::FOCUS_MODE_MACRO |
| //| ExynosCamera::FOCUS_MODE_FIXED |
| //| ExynosCamera::FOCUS_MODE_EDOF |
| //| ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO |
| //| ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE |
| //| ExynosCamera::FOCUS_MODE_TOUCH |
| ; |
| focusMode = ExynosCamera::FOCUS_MODE_AUTO; |
| |
| sceneModeList = |
| ExynosCamera::SCENE_MODE_AUTO |
| //| ExynosCamera::SCENE_MODE_ACTION |
| | ExynosCamera::SCENE_MODE_PORTRAIT |
| | ExynosCamera::SCENE_MODE_LANDSCAPE |
| | ExynosCamera::SCENE_MODE_NIGHT |
| //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT |
| //| ExynosCamera::SCENE_MODE_THEATRE |
| | ExynosCamera::SCENE_MODE_BEACH |
| | ExynosCamera::SCENE_MODE_SNOW |
| | ExynosCamera::SCENE_MODE_SUNSET |
| //| ExynosCamera::SCENE_MODE_STEADYPHOTO |
| | ExynosCamera::SCENE_MODE_FIREWORKS |
| | ExynosCamera::SCENE_MODE_SPORTS |
| | ExynosCamera::SCENE_MODE_PARTY |
| | ExynosCamera::SCENE_MODE_CANDLELIGHT; |
| sceneMode = ExynosCamera::SCENE_MODE_AUTO; |
| |
| whiteBalanceList = |
| ExynosCamera::WHITE_BALANCE_AUTO |
| | ExynosCamera::WHITE_BALANCE_INCANDESCENT |
| | ExynosCamera::WHITE_BALANCE_FLUORESCENT |
| //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT |
| | ExynosCamera::WHITE_BALANCE_DAYLIGHT |
| | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT |
| //| ExynosCamera::WHITE_BALANCE_TWILIGHT |
| //| ExynosCamera::WHITE_BALANCE_SHADE |
| ; |
| whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO; |
| |
| autoWhiteBalanceLockSupported = false; |
| autoWhiteBalanceLock = false; |
| |
| rotation = 0; |
| minExposure = -2; |
| maxExposure = 2; |
| exposure = 0; |
| |
| autoExposureLockSupported = false; |
| autoExposureLock = false; |
| |
| fps = 30; |
| focalLengthNum = 343; |
| focalLengthDen = 100; |
| supportVideoStabilization = false; |
| applyVideoStabilization = false; |
| videoStabilization = false; |
| maxNumMeteringAreas = 64; |
| maxNumDetectedFaces = 16; |
| maxNumFocusAreas = 2; |
| maxZoom = ZOOM_LEVEL_MAX; |
| hwZoomSupported = false; |
| zoom = 0; |
| gpsAltitude = 0; |
| gpsLatitude = 0; |
| gpsLongitude = 0; |
| gpsTimestamp = 0; |
| } |
| |
| ExynosCameraInfoS5K6A3::ExynosCameraInfoS5K6A3() |
| { |
| previewW = 1280; |
| previewH = 720; |
| previewColorFormat = V4L2_PIX_FMT_YVU420M; |
| videoW = 1280; |
| videoH = 720; |
| prefVideoPreviewW = 640; |
| prefVideoPreviewH = 360; |
| videoColorFormat = V4L2_PIX_FMT_NV12M; |
| pictureW = 1280; |
| pictureH = 720; |
| pictureColorFormat = V4L2_PIX_FMT_YUYV; |
| thumbnailW = 320; |
| thumbnailH = 240; |
| |
| antiBandingList = |
| ExynosCamera::ANTIBANDING_OFF |
| | ExynosCamera::ANTIBANDING_50HZ |
| | ExynosCamera::ANTIBANDING_60HZ |
| | ExynosCamera::ANTIBANDING_OFF; |
| antiBanding = ExynosCamera::ANTIBANDING_OFF; |
| |
| effectList = |
| ExynosCamera::EFFECT_NONE |
| | ExynosCamera::EFFECT_MONO |
| | ExynosCamera::EFFECT_NEGATIVE |
| //| ExynosCamera::EFFECT_SOLARIZE |
| | ExynosCamera::EFFECT_SEPIA |
| //| ExynosCamera::EFFECT_POSTERIZE |
| //| ExynosCamera::EFFECT_WHITEBOARD |
| //| ExynosCamera::EFFECT_BLACKBOARD |
| //| ExynosCamera::EFFECT_AQUA |
| ; |
| effect = ExynosCamera::EFFECT_NONE; |
| |
| flashModeList = |
| ExynosCamera::FLASH_MODE_OFF |
| //| ExynosCamera::FLASH_MODE_AUTO |
| //| ExynosCamera::FLASH_MODE_ON |
| //| ExynosCamera::FLASH_MODE_RED_EYE |
| //| ExynosCamera::FLASH_MODE_TORCH |
| ; |
| flashMode = ExynosCamera::FLASH_MODE_OFF; |
| |
| focusModeList = |
| // ExynosCamera::FOCUS_MODE_AUTO |
| //| ExynosCamera::FOCUS_MODE_INFINITY |
| //| ExynosCamera::FOCUS_MODE_MACRO |
| //| |
| ExynosCamera::FOCUS_MODE_FIXED |
| //| ExynosCamera::FOCUS_MODE_EDOF |
| //| ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO |
| //| ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE |
| //| ExynosCamera::FOCUS_MODE_TOUCH |
| ; |
| focusMode = ExynosCamera::FOCUS_MODE_FIXED; |
| |
| sceneModeList = |
| ExynosCamera::SCENE_MODE_AUTO |
| //| ExynosCamera::SCENE_MODE_ACTION |
| | ExynosCamera::SCENE_MODE_PORTRAIT |
| | ExynosCamera::SCENE_MODE_LANDSCAPE |
| | ExynosCamera::SCENE_MODE_NIGHT |
| //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT |
| //| ExynosCamera::SCENE_MODE_THEATRE |
| | ExynosCamera::SCENE_MODE_BEACH |
| | ExynosCamera::SCENE_MODE_SNOW |
| | ExynosCamera::SCENE_MODE_SUNSET |
| | ExynosCamera::SCENE_MODE_STEADYPHOTO |
| | ExynosCamera::SCENE_MODE_FIREWORKS |
| | ExynosCamera::SCENE_MODE_SPORTS |
| | ExynosCamera::SCENE_MODE_PARTY |
| | ExynosCamera::SCENE_MODE_CANDLELIGHT; |
| sceneMode = ExynosCamera::SCENE_MODE_AUTO; |
| |
| whiteBalanceList = |
| ExynosCamera::WHITE_BALANCE_AUTO |
| | ExynosCamera::WHITE_BALANCE_INCANDESCENT |
| | ExynosCamera::WHITE_BALANCE_FLUORESCENT |
| //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT |
| | ExynosCamera::WHITE_BALANCE_DAYLIGHT |
| | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT |
| //| ExynosCamera::WHITE_BALANCE_TWILIGHT |
| //| ExynosCamera::WHITE_BALANCE_SHADE |
| ; |
| whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO; |
| |
| autoWhiteBalanceLockSupported = true; |
| autoWhiteBalanceLock = false; |
| |
| rotation = 0; |
| minExposure = -2; |
| maxExposure = 2; |
| exposure = 0; |
| |
| autoExposureLockSupported = true; |
| autoExposureLock = false; |
| |
| fps = 30; |
| focalLengthNum = 9; |
| focalLengthDen = 10; |
| supportVideoStabilization = false; |
| applyVideoStabilization = false; |
| videoStabilization = false; |
| maxNumMeteringAreas = 64; |
| maxNumDetectedFaces = 16; |
| maxNumFocusAreas = 0; |
| maxZoom = ZOOM_LEVEL_MAX; |
| hwZoomSupported = false; |
| zoom = 0; |
| gpsAltitude = 0; |
| gpsLatitude = 0; |
| gpsLongitude = 0; |
| gpsTimestamp = 0; |
| } |
| |
| ExynosCameraInfoS5K4E5::ExynosCameraInfoS5K4E5() |
| { |
| previewW = 1920; |
| previewH = 1080; |
| previewColorFormat = V4L2_PIX_FMT_YVU420M; |
| videoW = 1920; |
| videoH = 1080; |
| prefVideoPreviewW = 640; |
| prefVideoPreviewH = 360; |
| videoColorFormat = V4L2_PIX_FMT_NV12M; |
| pictureW = 2560; |
| pictureH = 1920; |
| pictureColorFormat = V4L2_PIX_FMT_YUYV; |
| thumbnailW = 320; |
| thumbnailH = 240; |
| |
| antiBandingList = |
| ExynosCamera::ANTIBANDING_OFF |
| | ExynosCamera::ANTIBANDING_50HZ |
| | ExynosCamera::ANTIBANDING_60HZ |
| | ExynosCamera::ANTIBANDING_OFF; |
| antiBanding = ExynosCamera::ANTIBANDING_OFF; |
| |
| effectList = |
| ExynosCamera::EFFECT_NONE |
| | ExynosCamera::EFFECT_MONO |
| | ExynosCamera::EFFECT_NEGATIVE |
| //| ExynosCamera::EFFECT_SOLARIZE |
| | ExynosCamera::EFFECT_SEPIA |
| //| ExynosCamera::EFFECT_POSTERIZE |
| //| ExynosCamera::EFFECT_WHITEBOARD |
| //| ExynosCamera::EFFECT_BLACKBOARD |
| //| ExynosCamera::EFFECT_AQUA |
| ; |
| effect = ExynosCamera::EFFECT_NONE; |
| |
| flashModeList = |
| ExynosCamera::FLASH_MODE_OFF |
| | ExynosCamera::FLASH_MODE_AUTO |
| | ExynosCamera::FLASH_MODE_ON |
| //| ExynosCamera::FLASH_MODE_RED_EYE |
| | ExynosCamera::FLASH_MODE_TORCH; |
| flashMode = ExynosCamera::FLASH_MODE_OFF; |
| |
| focusModeList = |
| ExynosCamera::FOCUS_MODE_AUTO |
| | ExynosCamera::FOCUS_MODE_INFINITY |
| | ExynosCamera::FOCUS_MODE_MACRO |
| //| ExynosCamera::FOCUS_MODE_FIXED |
| //| ExynosCamera::FOCUS_MODE_EDOF |
| | ExynosCamera::FOCUS_MODE_CONTINUOUS_VIDEO |
| // | ExynosCamera::FOCUS_MODE_CONTINUOUS_PICTURE |
| | ExynosCamera::FOCUS_MODE_TOUCH |
| ; |
| focusMode = ExynosCamera::FOCUS_MODE_AUTO; |
| |
| sceneModeList = |
| ExynosCamera::SCENE_MODE_AUTO |
| //| ExynosCamera::SCENE_MODE_ACTION |
| | ExynosCamera::SCENE_MODE_PORTRAIT |
| | ExynosCamera::SCENE_MODE_LANDSCAPE |
| | ExynosCamera::SCENE_MODE_NIGHT |
| //| ExynosCamera::SCENE_MODE_NIGHT_PORTRAIT |
| //| ExynosCamera::SCENE_MODE_THEATRE |
| | ExynosCamera::SCENE_MODE_BEACH |
| | ExynosCamera::SCENE_MODE_SNOW |
| | ExynosCamera::SCENE_MODE_SUNSET |
| | ExynosCamera::SCENE_MODE_STEADYPHOTO |
| | ExynosCamera::SCENE_MODE_FIREWORKS |
| | ExynosCamera::SCENE_MODE_SPORTS |
| | ExynosCamera::SCENE_MODE_PARTY |
| | ExynosCamera::SCENE_MODE_CANDLELIGHT; |
| sceneMode = ExynosCamera::SCENE_MODE_AUTO; |
| |
| whiteBalanceList = |
| ExynosCamera::WHITE_BALANCE_AUTO |
| | ExynosCamera::WHITE_BALANCE_INCANDESCENT |
| | ExynosCamera::WHITE_BALANCE_FLUORESCENT |
| //| ExynosCamera::WHITE_BALANCE_WARM_FLUORESCENT |
| | ExynosCamera::WHITE_BALANCE_DAYLIGHT |
| | ExynosCamera::WHITE_BALANCE_CLOUDY_DAYLIGHT |
| //| ExynosCamera::WHITE_BALANCE_TWILIGHT |
| //| ExynosCamera::WHITE_BALANCE_SHADE |
| ; |
| whiteBalance = ExynosCamera::WHITE_BALANCE_AUTO; |
| |
| autoWhiteBalanceLockSupported = true; |
| autoWhiteBalanceLock = false; |
| |
| rotation = 0; |
| minExposure = -2; |
| maxExposure = 2; |
| exposure = 0; |
| |
| autoExposureLockSupported = true; |
| autoExposureLock = false; |
| |
| fps = 30; |
| focalLengthNum = 9; |
| focalLengthDen = 10; |
| supportVideoStabilization = true; |
| applyVideoStabilization = false; |
| videoStabilization = false; |
| maxNumMeteringAreas = 64; |
| maxNumDetectedFaces = 16; |
| maxNumFocusAreas = 2; |
| maxZoom = ZOOM_LEVEL_MAX; |
| hwZoomSupported = false; |
| zoom = 0; |
| gpsAltitude = 0; |
| gpsLatitude = 0; |
| gpsLongitude = 0; |
| gpsTimestamp = 0; |
| } |
| |
| ////////////////////////////////////////////////// |
| |
| #define PFX_NODE "/dev/video" |
| |
| #define M5MOLS_ENTITY_NAME "M5MOLS 5-001f" |
| #define PFX_SUBDEV_ENTITY_MIPI_CSIS "s5p-mipi-csis" |
| #define PFX_SUBDEV_ENTITY_FLITE "flite-subdev" |
| #define PFX_SUBDEV_ENTITY_GSC_CAP "gsc-cap-subdev" |
| #define PFX_VIDEODEV_ENTITY_FLITE "exynos-fimc-lite" |
| #define PFX_VIDEODEV_ENTITY_GSC_CAP "exynos-gsc" |
| |
| #define MEDIA_DEV_INTERNAL_ISP "/dev/media2" |
| #define MEDIA_DEV_EXTERNAL_ISP "/dev/media1" |
| #define ISP_VD_NODE_OFFSET (40) //INTERNAL_ISP |
| #define FLITE_VD_NODE_OFFSET (36) //External ISP |
| |
| #define VIDEO_NODE_PREVIEW_ID (3) |
| #define VIDEO_NODE_RECODING_ID (2) |
| #define VIDEO_NODE_SNAPSHOT_ID (1) |
| |
| #define ISP_SENSOR_MAX_ENTITIES 1 |
| #define ISP_SENSOR_PAD_SOURCE_FRONT 0 |
| #define ISP_SENSOR_PADS_NUM 1 |
| |
| #define ISP_FRONT_MAX_ENTITIES 1 |
| #define ISP_FRONT_PAD_SINK 0 |
| #define ISP_FRONT_PAD_SOURCE_BACK 1 |
| #define ISP_FRONT_PAD_SOURCE_BAYER 2 |
| #define ISP_FRONT_PAD_SOURCE_SCALERC 3 |
| #define ISP_FRONT_PADS_NUM 4 |
| |
| #define ISP_BACK_MAX_ENTITIES 1 |
| #define ISP_BACK_PAD_SINK 0 |
| #define ISP_BACK_PAD_SOURCE_3DNR 1 |
| #define ISP_BACK_PAD_SOURCE_SCALERP 2 |
| #define ISP_BACK_PADS_NUM 3 |
| |
| #define ISP_MODULE_NAME "exynos5-fimc-is" |
| #define ISP_SENSOR_ENTITY_NAME "exynos5-fimc-is-sensor" |
| #define ISP_FRONT_ENTITY_NAME "exynos5-fimc-is-front" |
| #define ISP_BACK_ENTITY_NAME "exynos5-fimc-is-back" |
| #define ISP_VIDEO_BAYER_NAME "exynos5-fimc-is-bayer" |
| #define ISP_VIDEO_SCALERC_NAME "exynos5-fimc-is-scalerc" |
| #define ISP_VIDEO_3DNR_NAME "exynos5-fimc-is-3dnr" |
| #define ISP_VIDEO_SCALERP_NAME "exynos5-fimc-is-scalerp" |
| |
| #define MIPI_NUM 1 |
| #define FLITE_NUM 1 |
| #define GSC_NUM 0 |
| |
| #define PFX_SUBDEV_NODE "/dev/v4l-subdev" |
| |
| /* |
| * V 4 L 2 F I M C E X T E N S I O N S |
| * |
| */ |
| #define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) |
| #define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) |
| #define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) |
| #define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) |
| #define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) |
| #define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) |
| |
| #define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) |
| #define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) |
| #define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) |
| #define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) |
| #define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) |
| #define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) |
| |
| #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') |
| |
| /* FOURCC for FIMC specific */ |
| #define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') |
| #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') |
| #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') |
| #define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') |
| |
| /////////////////////////////////////////////////// |
| // Google Official API : Camera.Parameters |
| // http://developer.android.com/reference/android/hardware/Camera.Parameters.html |
| /////////////////////////////////////////////////// |
| |
| ExynosCamera::ExynosCamera() : |
| m_flagCreate(false), |
| m_cameraId(CAMERA_ID_BACK), |
| m_defaultCameraInfo(NULL), |
| m_curCameraInfo(NULL), |
| m_jpegQuality(100), |
| m_jpegThumbnailQuality(100), |
| m_currentZoom(-1) |
| { |
| memset(&m_sensorDev, 0, sizeof(struct devInfo)); |
| memset(&m_mipiDev, 0, sizeof(struct devInfo)); |
| memset(&m_fliteDev, 0, sizeof(struct devInfo)); |
| memset(&m_gscPreviewDev, 0, sizeof(struct devInfo)); |
| memset(&m_gscVideoDev, 0, sizeof(struct devInfo)); |
| memset(&m_gscPictureDev, 0, sizeof(struct devInfo)); |
| |
| m_previewDev = NULL; |
| m_videoDev = NULL; |
| m_pictureDev = NULL; |
| |
| m_tryPreviewStop = true; |
| m_tryVideoStop = true; |
| m_tryPictureStop = true; |
| |
| m_flagStartFaceDetection = false; |
| m_flagAutoFocusRunning = false; |
| |
| m_sensorEntity = NULL; |
| m_mipiEntity = NULL; |
| m_fliteSdEntity = NULL; |
| m_fliteVdEntity = NULL; |
| m_gscSdEntity = NULL; |
| m_gscVdEntity = NULL; |
| m_ispSensorEntity = NULL; |
| m_ispFrontEntity = NULL; |
| m_ispBackEntity = NULL; |
| m_ispScalercEntity = NULL; |
| m_ispScalerpEntity = NULL; |
| m_isp3dnrEntity = NULL; |
| |
| |
| for (int i = 0; i < VIDEO_MAX_FRAME; i++) { |
| m_validPreviewBuf[i] = false; |
| m_validVideoBuf [i] = false; |
| m_validPictureBuf[i] = false; |
| } |
| |
| memset((void *)m_cameraName, 0, 32); |
| |
| m_internalISP = true; |
| m_media = NULL; |
| |
| memset(&mExifInfo, 0, sizeof(mExifInfo)); |
| } |
| |
| ExynosCamera::~ExynosCamera() |
| { |
| if (m_flagCreate == true) |
| destroy(); |
| } |
| |
| bool ExynosCamera::create(int cameraId) |
| { |
| int ret = 0; |
| unsigned int i; |
| int devNum; |
| char node[30]; |
| |
| struct media_link *links = NULL; |
| |
| if (m_flagCreate == true) { |
| ALOGE("ERR(%s):Already created", __func__); |
| return false; |
| } |
| |
| m_cameraId = cameraId; |
| |
| ExynosBuffer nullBuf; |
| |
| for (int i = 0; i < VIDEO_MAX_FRAME; i++) { |
| m_validPreviewBuf[i] = false; |
| m_validVideoBuf [i] = false; |
| m_validPictureBuf[i] = false; |
| |
| m_previewBuf[i] = nullBuf; |
| m_videoBuf[i] = nullBuf; |
| m_pictureBuf[i] = nullBuf; |
| } |
| |
| if (m_cameraId == CAMERA_ID_BACK) |
| m_internalISP = true; |
| // m_internalISP = false; // external ISP. |
| else |
| m_internalISP = true; |
| |
| if (m_internalISP == true) { |
| ////////////////////////////// |
| // internal ISP |
| ////////////////////////////// |
| // media device open |
| m_media = exynos_media_open(MEDIA_DEV_INTERNAL_ISP); |
| if (m_media == NULL) { |
| ALOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno)); |
| goto err; |
| } |
| |
| ////////////////// |
| // GET ENTITIES |
| ////////////////// |
| // ISP sensor subdev |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_SENSOR_ENTITY_NAME); |
| m_ispSensorEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| // ISP front subdev |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_FRONT_ENTITY_NAME); |
| m_ispFrontEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| // ISP back subdev |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_BACK_ENTITY_NAME); |
| m_ispBackEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| // ISP ScalerC video node |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_VIDEO_SCALERC_NAME); |
| m_ispScalercEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| // ISP ScalerP video node |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_VIDEO_SCALERP_NAME); |
| m_ispScalerpEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| // ISP 3DNR video node |
| memset(&node, 0x00, sizeof(node)); |
| strcpy(node, ISP_VIDEO_3DNR_NAME); |
| m_isp3dnrEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| |
| ALOGV("DEBUG(%s):m_ispSensorEntity : numlink : %d", __func__, m_ispSensorEntity->num_links); |
| ALOGV("DEBUG(%s):m_ispFrontEntity : numlink : %d", __func__, m_ispFrontEntity->num_links); |
| ALOGV("DEBUG(%s):m_ispBackEntity : numlink : %d", __func__, m_ispBackEntity->num_links); |
| ALOGV("DEBUG(%s):m_ispScalercEntity : numlink : %d", __func__, m_ispScalercEntity->num_links); |
| ALOGV("DEBUG(%s):m_ispScalerpEntity : numlink : %d", __func__, m_ispScalerpEntity->num_links); |
| ALOGV("DEBUG(%s):m_isp3dnrEntity : numlink : %d", __func__, m_isp3dnrEntity->num_links); |
| |
| ////////////////// |
| // SETUP LINKS |
| ////////////////// |
| // SENSOR TO FRONT |
| links = m_ispSensorEntity->links; |
| if (links == NULL || |
| links->source->entity != m_ispSensorEntity || |
| links->sink->entity != m_ispFrontEntity) { |
| ALOGE("ERR(%s):Can not make link isp_sensor to isp_front", __func__); |
| goto err; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Can not make setup isp_sensor to isp_front", __func__); |
| goto err; |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] Sensor to front", __func__); |
| |
| // FRONT TO BACK |
| for (i = 0; i < m_ispFrontEntity->num_links; i++) { |
| links = &m_ispFrontEntity->links[i]; |
| if (links == NULL || |
| links->source->entity != m_ispFrontEntity || |
| links->sink->entity != m_ispBackEntity) { |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_ispFrontEntity : %p", __func__, i, |
| links->source->entity, m_ispFrontEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_ispBackEntity : %p", __func__, i, |
| links->sink->entity, m_ispBackEntity); |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Can not make setup isp_front to isp_back", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] front to back", __func__); |
| |
| // BACK TO ScalerP Video |
| for (i = 0; i < m_ispBackEntity->num_links; i++) { |
| links = &m_ispBackEntity->links[i]; |
| if (links == NULL || |
| links->source->entity != m_ispBackEntity || |
| links->sink->entity != m_ispScalerpEntity) { |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_ispBackEntity : %p", __func__, i, |
| links->source->entity, m_ispBackEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_ispScalerpEntity : %p", __func__, i, |
| links->sink->entity, m_ispScalerpEntity); |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Can not make setup isp_back to scalerP", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] back to scalerP", __func__); |
| |
| sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_PREVIEW_ID)); |
| m_gscPreviewDev.fd = exynos_v4l2_open(node, O_RDWR, 0); |
| if (m_gscPreviewDev.fd <= 0) { |
| ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno)); |
| goto err; |
| } |
| m_previewDev = &m_gscPreviewDev; |
| |
| sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_RECODING_ID)); |
| m_gscVideoDev.fd = exynos_v4l2_open(node, O_RDWR, 0); |
| if (m_gscVideoDev.fd <= 0) { |
| ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno)); |
| goto err; |
| } |
| m_videoDev = &m_gscVideoDev; |
| |
| sprintf(node, "%s%d", PFX_NODE, (ISP_VD_NODE_OFFSET + VIDEO_NODE_SNAPSHOT_ID)); |
| m_gscPictureDev.fd = exynos_v4l2_open(node, O_RDWR, 0); |
| if (m_gscPictureDev.fd <= 0) { |
| ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno)); |
| goto err; |
| } |
| m_pictureDev = &m_gscPictureDev; |
| |
| } else { |
| ////////////////////////////// |
| // external ISP |
| ////////////////////////////// |
| // media device open |
| m_media = exynos_media_open(MEDIA_DEV_EXTERNAL_ISP); |
| if (m_media == NULL) { |
| ALOGE("ERR(%s):Cannot open media device (error : %s)", __func__, strerror(errno)); |
| goto err; |
| } |
| |
| ////////////////// |
| // GET ENTITIES |
| ////////////////// |
| // camera subdev |
| strcpy(node, M5MOLS_ENTITY_NAME); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_sensorEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_sensorEntity : 0x%p", __func__, m_sensorEntity); |
| |
| // mipi subdev |
| sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_MIPI_CSIS, MIPI_NUM); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_mipiEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_mipiEntity : 0x%p", __func__, m_mipiEntity); |
| |
| // fimc-lite subdev |
| sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_FLITE, FLITE_NUM); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_fliteSdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_fliteSdEntity : 0x%p", __func__, m_fliteSdEntity); |
| |
| // fimc-lite videodev |
| sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_FLITE, FLITE_NUM); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_fliteVdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_fliteVdEntity : 0x%p", __func__, m_fliteVdEntity); |
| |
| // gscaler subdev |
| sprintf(node, "%s.%d", PFX_SUBDEV_ENTITY_GSC_CAP, GSC_NUM); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_gscSdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_gscSdEntity : 0x%p", __func__, m_gscSdEntity); |
| |
| // gscaler videodev |
| sprintf(node, "%s.%d", PFX_VIDEODEV_ENTITY_GSC_CAP, GSC_NUM); |
| ALOGV("DEBUG(%s):node : %s", __func__, node); |
| m_gscVdEntity = exynos_media_get_entity_by_name(m_media, node, strlen(node)); |
| ALOGV("DEBUG(%s):m_gscVdEntity : 0x%p", __func__, m_gscVdEntity); |
| |
| ALOGV("DEBUG(%s):sensor_sd : numlink : %d", __func__, m_sensorEntity->num_links); |
| ALOGV("DEBUG(%s):mipi_sd : numlink : %d", __func__, m_mipiEntity->num_links); |
| ALOGV("DEBUG(%s):flite_sd : numlink : %d", __func__, m_fliteSdEntity->num_links); |
| ALOGV("DEBUG(%s):flite_vd : numlink : %d", __func__, m_fliteVdEntity->num_links); |
| ALOGV("DEBUG(%s):gsc_sd : numlink : %d", __func__, m_gscSdEntity->num_links); |
| ALOGV("DEBUG(%s):gsc_vd : numlink : %d", __func__, m_gscVdEntity->num_links); |
| |
| ////////////////// |
| // SETUP LINKS |
| ////////////////// |
| // sensor subdev to mipi subdev |
| links = m_sensorEntity->links; |
| if (links == NULL || |
| links->source->entity != m_sensorEntity || |
| links->sink->entity != m_mipiEntity) { |
| ALOGE("ERR(%s):Cannot make link camera sensor to mipi", __func__); |
| goto err; |
| } |
| |
| if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Cannot make setup camera sensor to mipi", __func__); |
| goto err; |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] sensor subdev to mipi subdev", __func__); |
| |
| // mipi subdev to fimc-lite subdev |
| for (i = 0; i < m_mipiEntity->num_links; i++) { |
| links = &m_mipiEntity->links[i]; |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_mipiEntity : %p", __func__, i, |
| links->source->entity, m_mipiEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_fliteSdEntity : %p", __func__, i, |
| links->sink->entity, m_fliteSdEntity); |
| if (links == NULL || |
| links->source->entity != m_mipiEntity || |
| links->sink->entity != m_fliteSdEntity) { |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Cannot make setup mipi subdev to fimc-lite subdev", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] mipi subdev to fimc-lite subdev", __func__); |
| |
| // fimc-lite subdev TO fimc-lite video dev |
| for (i = 0; i < m_fliteSdEntity->num_links; i++) { |
| links = &m_fliteSdEntity->links[i]; |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_fliteSdEntity : %p", __func__, i, |
| links->source->entity, m_fliteSdEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_fliteVdEntity : %p", __func__, i, |
| links->sink->entity, m_fliteVdEntity); |
| if (links == NULL || |
| links->source->entity != m_fliteSdEntity || |
| links->sink->entity != m_fliteVdEntity) { |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Cannot make setup fimc-lite subdev to fimc-lite video dev", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] fimc-lite subdev to fimc-lite video dev", __func__); |
| |
| // fimc-lite subdev to gscaler subdev |
| for (i = 0; i < m_gscSdEntity->num_links; i++) { |
| links = &m_gscSdEntity->links[i]; |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_fliteSdEntity : %p", __func__, i, |
| links->source->entity, m_fliteSdEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_gscSdEntity : %p", __func__, i, |
| links->sink->entity, m_gscSdEntity); |
| if (links == NULL || |
| links->source->entity != m_fliteSdEntity || |
| links->sink->entity != m_gscSdEntity) { |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Cannot make setup fimc-lite subdev to gscaler subdev", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] fimc-lite subdev to gscaler subdev", __func__); |
| |
| // gscaler subdev to gscaler video dev |
| for (i = 0; i < m_gscVdEntity->num_links; i++) { |
| links = &m_gscVdEntity->links[i]; |
| ALOGV("DEBUG(%s):i=%d: links->source->entity : %p, m_gscSdEntity : %p", __func__, i, |
| links->source->entity, m_gscSdEntity); |
| ALOGV("DEBUG(%s):i=%d: links->sink->entity : %p, m_gscVdEntity : %p", __func__, i, |
| links->sink->entity, m_gscVdEntity); |
| if (links == NULL || |
| links->source->entity != m_gscSdEntity || |
| links->sink->entity != m_gscVdEntity) { |
| continue; |
| } else if (exynos_media_setup_link(m_media, links->source, links->sink, MEDIA_LNK_FL_ENABLED) < 0) { |
| ALOGE("ERR(%s):Cannot make setup gscaler subdev to gscaler video dev", __func__); |
| goto err; |
| } |
| } |
| ALOGV("DEBUG(%s):[LINK SUCCESS] gscaler subdev to gscaler video dev", __func__); |
| |
| sprintf(node, "%s%d", PFX_NODE, (FLITE_VD_NODE_OFFSET + VIDEO_NODE_PREVIEW_ID)); |
| m_fliteDev.fd = exynos_v4l2_open(node, O_RDWR, 0); |
| if (m_fliteDev.fd <= 0) { |
| ALOGE("ERR(%s):exynos_v4l2_open(%s) fail (error : %s)", __func__, node, strerror(errno)); |
| goto err; |
| } |
| m_previewDev = &m_fliteDev; |
| m_videoDev = &m_fliteDev; |
| m_pictureDev = &m_fliteDev; |
| } |
| |
| m_previewDev->flagStart = false; |
| m_videoDev->flagStart = false; |
| m_pictureDev->flagStart = false; |
| |
| m_tryPreviewStop = true; |
| m_tryVideoStop = true; |
| m_tryPictureStop = true; |
| |
| m_flagStartFaceDetection = false; |
| m_flagAutoFocusRunning = false; |
| |
| if (exynos_v4l2_enuminput(m_previewDev->fd, m_cameraId, m_cameraName) == false) { |
| ALOGE("ERR(%s):exynos_v4l2_enuminput(%d, %s) fail", __func__, m_cameraId, m_cameraName); |
| goto err; |
| } |
| |
| // HACK |
| if (m_cameraId == CAMERA_ID_BACK) |
| strcpy(m_cameraName, "S5K4E5"); |
| else |
| strcpy(m_cameraName, "S5K6A3"); |
| |
| if (exynos_v4l2_s_input(m_previewDev->fd, m_cameraId) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_input() fail", __func__); |
| goto err; |
| } |
| |
| if (strcmp((const char*)m_cameraName, "S5K4E5") == 0) { |
| m_defaultCameraInfo = new ExynosCameraInfoS5K4E5; |
| m_curCameraInfo = new ExynosCameraInfoS5K4E5; |
| } else if (strcmp((const char*)m_cameraName, "S5K6A3") == 0) { |
| m_defaultCameraInfo = new ExynosCameraInfoS5K6A3; |
| m_curCameraInfo = new ExynosCameraInfoS5K6A3; |
| } else if (strcmp((const char*)m_cameraName, "M5M0") == 0) { |
| m_defaultCameraInfo = new ExynosCameraInfoM5M0; |
| m_curCameraInfo = new ExynosCameraInfoM5M0; |
| } else { |
| ALOGE("ERR(%s):invalid camera Name (%s) fail", __func__, m_cameraName); |
| goto err; |
| } |
| |
| m_setExifFixedAttribute(); |
| |
| m_flagCreate = true; |
| return true; |
| |
| err: |
| if (m_defaultCameraInfo) |
| delete m_defaultCameraInfo; |
| m_defaultCameraInfo = NULL; |
| |
| if (m_curCameraInfo) |
| delete m_curCameraInfo; |
| m_curCameraInfo = NULL; |
| |
| if (0 < m_videoDev->fd) |
| exynos_v4l2_close(m_videoDev->fd); |
| m_videoDev->fd = 0; |
| |
| if (0 < m_pictureDev->fd) |
| exynos_v4l2_close(m_pictureDev->fd); |
| m_pictureDev->fd = 0; |
| |
| if (0 < m_previewDev->fd) |
| exynos_v4l2_close(m_previewDev->fd); |
| m_previewDev->fd = 0; |
| |
| if (m_media) |
| exynos_media_close(m_media); |
| m_media = NULL; |
| |
| return false; |
| } |
| |
| bool ExynosCamera::destroy(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created", __func__); |
| return false; |
| } |
| |
| if (m_pictureDev->flagStart == true) |
| stopPicture(); |
| |
| if (m_videoDev->flagStart == true) |
| stopVideo(); |
| |
| if (m_previewDev->flagStart == true) |
| stopPreview(); |
| |
| if (m_defaultCameraInfo) |
| delete m_defaultCameraInfo; |
| m_defaultCameraInfo = NULL; |
| |
| if (m_curCameraInfo) |
| delete m_curCameraInfo; |
| m_curCameraInfo = NULL; |
| |
| // close m_previewDev->fd after stopVideo() because stopVideo() |
| // uses m_previewDev->fd to change frame rate |
| if (0 < m_videoDev->fd) |
| exynos_v4l2_close(m_videoDev->fd); |
| m_videoDev->fd = 0; |
| |
| if (0 < m_pictureDev->fd) |
| exynos_v4l2_close(m_pictureDev->fd); |
| m_pictureDev->fd = 0; |
| |
| if (0 < m_previewDev->fd) |
| exynos_v4l2_close(m_previewDev->fd); |
| m_previewDev->fd = 0; |
| |
| if (m_media) |
| exynos_media_close(m_media); |
| m_media = NULL; |
| |
| m_flagCreate = false; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::flagCreate(void) |
| { |
| return m_flagCreate; |
| } |
| |
| int ExynosCamera::getCameraId(void) |
| { |
| return m_cameraId; |
| } |
| |
| char *ExynosCamera::getCameraName(void) |
| { |
| return m_cameraName; |
| } |
| |
| int ExynosCamera::getPreviewFd(void) |
| { |
| return m_previewDev->fd; |
| } |
| |
| int ExynosCamera::getPictureFd(void) |
| { |
| return m_pictureDev->fd; |
| } |
| |
| int ExynosCamera::getVideoFd(void) |
| { |
| return m_videoDev->fd; |
| } |
| |
| bool ExynosCamera::startPreview(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| if (m_previewDev->flagStart == false) { |
| if (m_setWidthHeight(PREVIEW_MODE, |
| m_previewDev->fd, |
| &m_previewDev->events, |
| m_curCameraInfo->previewW, |
| m_curCameraInfo->previewH, |
| m_curCameraInfo->previewColorFormat, |
| m_previewBuf, |
| m_validPreviewBuf) == false) { |
| ALOGE("ERR(%s):m_setWidthHeight() fail", __func__); |
| return false; |
| } |
| |
| if (setPreviewFrameRate(m_curCameraInfo->fps) == false) |
| ALOGE("ERR(%s):Fail toggle setPreviewFrameRate(%d)", |
| __func__, m_curCameraInfo->fps); |
| |
| if (exynos_v4l2_streamon(m_previewDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__); |
| return false; |
| } |
| |
| if (m_curCameraInfo->focusMode == FOCUS_MODE_CONTINUOUS_VIDEO |
| || m_curCameraInfo->focusMode == FOCUS_MODE_CONTINUOUS_PICTURE) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_CAF_START_STOP, CAF_START) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| |
| m_tryPreviewStop = false; |
| m_previewDev->flagStart = true; |
| |
| /* TODO */ |
| /* DIS is only supported BACK camera(4E5) currently. */ |
| #ifdef USE_DIS |
| bool toggle = getVideoStabilization(); |
| |
| if (setVideoStabilization(toggle) == false) |
| ALOGE("ERR(%s):setVideoStabilization() fail", __func__); |
| #endif |
| |
| #ifdef USE_3DNR |
| if (m_recordingHint == true && getCameraId() == CAMERA_ID_BACK) { |
| if (set3DNR(true) == false) |
| ALOGE("ERR(%s):set3DNR() fail", __func__); |
| } |
| #endif |
| |
| #ifdef USE_ODC |
| if (setODC(true) == false) |
| ALOGE("ERR(%s):setODC() fail", __func__); |
| #endif |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::stopPreview(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| if (m_previewDev->flagStart == true) { |
| |
| if (m_curCameraInfo->flashMode == FLASH_MODE_TORCH) |
| setFlashMode(FLASH_MODE_OFF); |
| |
| m_tryPreviewStop = true; |
| |
| // skip stopPreview |
| if ( (m_previewDev == m_videoDev && m_tryVideoStop == false) |
| || (m_previewDev == m_pictureDev && m_tryPictureStop == false)) |
| return true; |
| |
| /* TODO */ |
| /* Can not use 3DNR, ODC and DIS function because HW problem at exynos5250 EVT0 */ |
| #ifdef USE_3DNR |
| if (set3DNR(false) == false) |
| ALOGE("ERR(%s):set3DNR() fail", __func__); |
| #endif |
| |
| #ifdef USE_ODC |
| if (setODC(false) == false) |
| ALOGE("ERR(%s):setODC() fail", __func__); |
| #endif |
| |
| if (exynos_v4l2_streamoff(m_previewDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__); |
| return false; |
| } |
| |
| struct v4l2_requestbuffers req; |
| req.count = 0; |
| req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| req.memory = V4L2_MEMORY_DMABUF; |
| |
| if (exynos_v4l2_reqbufs(m_previewDev->fd, &req) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__); |
| return false; |
| } |
| |
| m_previewDev->flagStart = false; |
| |
| m_flagStartFaceDetection = false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::flagStartPreview(void) |
| { |
| return m_previewDev->flagStart; |
| } |
| |
| int ExynosCamera::getPreviewMaxBuf(void) |
| { |
| return VIDEO_MAX_FRAME; |
| } |
| |
| bool ExynosCamera::setPreviewBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= buf->reserved.p) { |
| ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME); |
| return false; |
| } |
| |
| m_previewBuf[buf->reserved.p] = *buf; |
| |
| // HACK : Driver not yet support cb,cr of YV12 |
| m_previewBuf[buf->reserved.p].virt.extP[1] = buf->virt.extP[2]; |
| m_previewBuf[buf->reserved.p].virt.extP[2] = buf->virt.extP[1]; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::getPreviewBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_previewDev->flagStart == false) { |
| ALOGE("ERR(%s):Not yet preview started fail", __func__); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| if (m_previewBuf[0].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_dqbuf(m_previewDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= v4l2_buf.index) { |
| ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index); |
| return false; |
| } |
| |
| *buf = m_previewBuf[v4l2_buf.index]; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::putPreviewBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_validPreviewBuf[buf->reserved.p] == false) { |
| ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.index = buf->reserved.p; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| v4l2_buf.m.planes[i].m.fd= m_previewBuf[buf->reserved.p].fd.extFd[i]; |
| v4l2_buf.m.planes[i].length = m_previewBuf[buf->reserved.p].size.extS[i]; |
| |
| if (m_previewBuf[buf->reserved.p].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_qbuf(m_previewDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setVideoSize(int w, int h) |
| { |
| m_curCameraInfo->videoW = w; |
| m_curCameraInfo->videoH = h; |
| |
| #ifdef USE_3DNR_DMAOUT |
| // HACK : Video 3dnr port support resize. So, we must make max size video w, h |
| m_curCameraInfo->videoW = m_defaultCameraInfo->videoW; |
| m_curCameraInfo->videoH = m_defaultCameraInfo->videoH; |
| #endif |
| return true; |
| } |
| |
| bool ExynosCamera::getVideoSize(int *w, int *h) |
| { |
| *w = m_curCameraInfo->videoW; |
| *h = m_curCameraInfo->videoH; |
| return true; |
| } |
| |
| bool ExynosCamera::setVideoFormat(int colorFormat) |
| { |
| m_curCameraInfo->videoColorFormat = colorFormat; |
| return true; |
| } |
| |
| int ExynosCamera::getVideoFormat(void) |
| { |
| return m_curCameraInfo->videoColorFormat; |
| } |
| |
| bool ExynosCamera::startVideo(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| #ifdef USE_3DNR_DMAOUT |
| if (m_videoDev->flagStart == false) { |
| if (m_setWidthHeight(VIDEO_MODE, |
| m_videoDev->fd, |
| &m_videoDev->events, |
| m_curCameraInfo->videoW, |
| m_curCameraInfo->videoH, |
| m_curCameraInfo->videoColorFormat, |
| m_videoBuf, |
| m_validVideoBuf) == false) { |
| ALOGE("ERR(%s):m_setWidthHeight() fail", __func__); |
| return false; |
| } |
| |
| if (exynos_v4l2_streamon(m_videoDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__); |
| return false; |
| } |
| |
| m_tryVideoStop = false; |
| m_videoDev->flagStart = true; |
| } |
| #endif |
| |
| return true; |
| } |
| |
| bool ExynosCamera::stopVideo(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| if (m_videoDev->flagStart == true) { |
| |
| m_tryVideoStop = true; |
| |
| // skip stopVideo |
| if ( (m_videoDev == m_previewDev && m_tryPreviewStop == false) |
| || (m_videoDev == m_pictureDev && m_tryPictureStop == false)) |
| return true; |
| |
| if (exynos_v4l2_streamoff(m_videoDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__); |
| return false; |
| } |
| struct v4l2_requestbuffers req; |
| req.count = 0; |
| req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| req.memory = V4L2_MEMORY_DMABUF; |
| |
| if (exynos_v4l2_reqbufs(m_videoDev->fd, &req) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__); |
| return false; |
| } |
| |
| m_videoDev->flagStart = false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::flagStartVideo(void) |
| { |
| return m_videoDev->flagStart; |
| } |
| |
| int ExynosCamera::getVideoMaxBuf(void) |
| { |
| return VIDEO_MAX_FRAME; |
| } |
| |
| bool ExynosCamera::setVideoBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= buf->reserved.p) { |
| ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME); |
| return false; |
| } |
| |
| m_videoBuf[buf->reserved.p] = *buf; |
| return true; |
| } |
| |
| bool ExynosCamera::getVideoBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_videoDev->flagStart == false) { |
| ALOGE("ERR(%s):Not yet video started fail", __func__); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| if (m_videoBuf[0].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_dqbuf(m_videoDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= v4l2_buf.index) { |
| ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index); |
| return false; |
| } |
| |
| *buf = m_videoBuf[v4l2_buf.index]; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::putVideoBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_videoDev->flagStart == false) { |
| /* this can happen when recording frames are returned after |
| * the recording is stopped at the driver level. we don't |
| * need to return the buffers in this case and we've seen |
| * cases where fimc could crash if we called qbuf and it |
| * wasn't expecting it. |
| */ |
| ALOGV("DEBUG(%s):recording not in progress, ignoring", __func__); |
| return true; |
| } |
| |
| if (m_validVideoBuf[buf->reserved.p] == false) { |
| ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.index = buf->reserved.p; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| v4l2_buf.m.planes[i].m.fd = (unsigned long)m_videoBuf[buf->reserved.p].fd.extFd[i]; |
| v4l2_buf.m.planes[i].length = m_videoBuf[buf->reserved.p].size.extS[i]; |
| |
| if (m_videoBuf[buf->reserved.p].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_qbuf(m_videoDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::startPicture(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| if (m_pictureDev->flagStart == false) { |
| if (m_setWidthHeight(PICTURE_MODE, |
| m_pictureDev->fd, |
| &m_pictureDev->events, |
| m_curCameraInfo->pictureW, |
| m_curCameraInfo->pictureH, |
| m_curCameraInfo->pictureColorFormat, |
| m_pictureBuf, |
| m_validPictureBuf) == false) { |
| ALOGE("ERR(%s):m_setWidthHeight() fail", __func__); |
| return false; |
| } |
| |
| if (exynos_v4l2_streamon(m_pictureDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamon() fail", __func__); |
| return false; |
| } |
| |
| m_tryPictureStop = false; |
| m_pictureDev->flagStart = true; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::stopPicture(void) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet Created", __func__); |
| return false; |
| } |
| |
| if (m_pictureDev->flagStart == true) { |
| |
| m_tryPictureStop = true; |
| |
| // skip stopPicture |
| if ( (m_pictureDev == m_previewDev && m_tryPreviewStop == false) |
| || (m_pictureDev == m_videoDev && m_tryVideoStop == false)) |
| return true; |
| |
| if (exynos_v4l2_streamoff(m_pictureDev->fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_streamoff() fail", __func__); |
| return false; |
| } |
| |
| struct v4l2_requestbuffers req; |
| req.count = 0; |
| req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| req.memory = V4L2_MEMORY_DMABUF; |
| |
| if (exynos_v4l2_reqbufs(m_pictureDev->fd, &req) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_reqbufs() fail", __func__); |
| return false; |
| } |
| |
| m_pictureDev->flagStart = false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::flagStartPicture(void) |
| { |
| return m_pictureDev->flagStart; |
| } |
| |
| int ExynosCamera::getPictureMaxBuf(void) |
| { |
| return VIDEO_MAX_FRAME; |
| } |
| |
| bool ExynosCamera::setPictureBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= buf->reserved.p) { |
| ALOGE("ERR(%s):index(%d) must smaller than %d", __func__, buf->reserved.p, VIDEO_MAX_FRAME); |
| return false; |
| } |
| |
| m_pictureBuf[buf->reserved.p] = *buf; |
| return true; |
| } |
| |
| bool ExynosCamera::getPictureBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_pictureDev->flagStart == false) { |
| ALOGE("ERR(%s):Not yet picture started fail", __func__); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| if (m_pictureBuf[0].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_dqbuf(m_pictureDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_dqbuf() fail", __func__); |
| return false; |
| } |
| |
| if (VIDEO_MAX_FRAME <= v4l2_buf.index) { |
| ALOGE("ERR(%s):wrong index = %d", __func__, v4l2_buf.index); |
| return false; |
| } |
| |
| *buf = m_pictureBuf[v4l2_buf.index]; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::putPictureBuf(ExynosBuffer *buf) |
| { |
| if (m_flagCreate == false) { |
| ALOGE("ERR(%s):Not yet created fail", __func__); |
| return false; |
| } |
| |
| if (m_pictureDev->flagStart == false) { |
| ALOGE("ERR(%s):Not yet picture started fail", __func__); |
| return false; |
| } |
| |
| if (m_validPictureBuf[buf->reserved.p] == false) { |
| ALOGE("ERR(%s):Invalid index(%d)", __func__, buf->reserved.p); |
| return false; |
| } |
| |
| struct v4l2_buffer v4l2_buf; |
| struct v4l2_plane planes[VIDEO_MAX_PLANES]; |
| |
| v4l2_buf.m.planes = planes; |
| v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| v4l2_buf.memory = V4L2_MEMORY_DMABUF; |
| v4l2_buf.index = buf->reserved.p; |
| v4l2_buf.length = 0; |
| |
| for (int i = 0; i < 3; i++) { |
| v4l2_buf.m.planes[i].m.fd = (unsigned long)m_pictureBuf[buf->reserved.p].fd.extFd[i]; |
| v4l2_buf.m.planes[i].length = m_pictureBuf[buf->reserved.p].size.extS[i]; |
| |
| if (m_pictureBuf[buf->reserved.p].size.extS[i] != 0) |
| v4l2_buf.length++; |
| } |
| |
| if (exynos_v4l2_qbuf(m_pictureDev->fd, &v4l2_buf) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_qbuf() fail", __func__); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::yuv2Jpeg(ExynosBuffer *yuvBuf, |
| ExynosBuffer *jpegBuf, |
| ExynosRect *rect) |
| { |
| unsigned char *addr; |
| |
| ExynosJpegEncoderForCamera jpegEnc; |
| bool ret = false; |
| |
| unsigned int *yuvSize = yuvBuf->size.extS; |
| |
| if (jpegEnc.create()) { |
| ALOGE("ERR(%s):jpegEnc.create() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.setQuality(m_jpegQuality)) { |
| ALOGE("ERR(%s):jpegEnc.setQuality() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.setSize(rect->w, rect->h)) { |
| ALOGE("ERR(%s):jpegEnc.setSize() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.setColorFormat(rect->colorFormat)) { |
| ALOGE("ERR(%s):jpegEnc.setColorFormat() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) { |
| ALOGE("ERR(%s):jpegEnc.setJpegFormat() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (m_curCameraInfo->thumbnailW != 0 && m_curCameraInfo->thumbnailH != 0) { |
| mExifInfo.enableThumb = true; |
| if (jpegEnc.setThumbnailSize(m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH)) { |
| ALOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __func__, m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH); |
| goto jpeg_encode_done; |
| } |
| |
| if (0 < m_jpegThumbnailQuality && m_jpegThumbnailQuality <= 100) { |
| if (jpegEnc.setThumbnailQuality(m_jpegThumbnailQuality)) { |
| ALOGE("ERR(%s):jpegEnc.setThumbnailSize(%d, %d) fail", __func__, m_curCameraInfo->thumbnailW, m_curCameraInfo->thumbnailH); |
| goto jpeg_encode_done; |
| } |
| } |
| |
| m_setExifChangedAttribute(&mExifInfo, rect); |
| } else { |
| mExifInfo.enableThumb = false; |
| } |
| |
| if (jpegEnc.setInBuf((char **)&(yuvBuf->virt.p), (int *)yuvSize)) { |
| ALOGE("ERR(%s):jpegEnc.setInBuf() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.setOutBuf(jpegBuf->virt.p, jpegBuf->size.extS[0] + jpegBuf->size.extS[1] + jpegBuf->size.extS[2])) { |
| ALOGE("ERR(%s):jpegEnc.setOutBuf() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.updateConfig()) { |
| ALOGE("ERR(%s):jpegEnc.updateConfig() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| if (jpegEnc.encode((int *)&jpegBuf->size.s, &mExifInfo)) { |
| ALOGE("ERR(%s):jpegEnc.encode() fail", __func__); |
| goto jpeg_encode_done; |
| } |
| |
| ret = true; |
| |
| jpeg_encode_done: |
| |
| if (jpegEnc.flagCreate() == true) |
| jpegEnc.destroy(); |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::autoFocus(void) |
| { |
| if (m_previewDev->fd <= 0) { |
| ALOGE("ERR(%s):Camera was closed", __func__); |
| return false; |
| } |
| |
| if (m_flagAutoFocusRunning == true) { |
| ALOGD("DEBUG(%s):m_flagAutoFocusRunning == true", __func__); |
| return true; |
| } |
| |
| switch (m_curCameraInfo->focusMode) { |
| case FOCUS_MODE_AUTO: |
| case FOCUS_MODE_INFINITY: |
| case FOCUS_MODE_MACRO: |
| if (m_touchAFMode == true) { |
| if (setFocusMode(FOCUS_MODE_TOUCH) == false) { |
| ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__); |
| return false; |
| } |
| } else { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| break; |
| case FOCUS_MODE_CONTINUOUS_VIDEO: |
| case FOCUS_MODE_CONTINUOUS_PICTURE: |
| /* Doing nothing. Because we assume that continuous focus mode is |
| always focused on. */ |
| break; |
| case FOCUS_MODE_TOUCH: |
| if (setFocusMode(FOCUS_MODE_TOUCH) == false) { |
| ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__); |
| return false; |
| } |
| break; |
| case FOCUS_MODE_FIXED: |
| break; |
| case FOCUS_MODE_EDOF: |
| default: |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, m_curCameraInfo->focusMode); |
| return false; |
| break; |
| } |
| |
| m_flagAutoFocusRunning = true; |
| |
| return true; |
| } |
| |
| bool ExynosCamera::cancelAutoFocus(void) |
| { |
| if (m_previewDev->fd <= 0) { |
| ALOGE("ERR(%s):Camera was closed", __func__); |
| return false; |
| } |
| |
| if (m_flagAutoFocusRunning == false) { |
| ALOGV("DEBUG(%s):m_flagAutoFocusRunning == false", __func__); |
| return true; |
| } |
| |
| switch (m_curCameraInfo->focusMode) { |
| case FOCUS_MODE_AUTO: |
| case FOCUS_MODE_INFINITY: |
| case FOCUS_MODE_MACRO: |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| break; |
| case FOCUS_MODE_CONTINUOUS_VIDEO: |
| case FOCUS_MODE_CONTINUOUS_PICTURE: |
| /* Doing nothing. Because we assume that continuous focus mode is |
| always focused on. */ |
| break; |
| case FOCUS_MODE_TOUCH: |
| if (setFocusMode(FOCUS_MODE_TOUCH) == false) { |
| ALOGE("ERR(%s): %d: setFocusMode(FOCUS_MODE_TOUCH) fail", __func__, __LINE__); |
| return false; |
| } |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_FIXED: |
| break; |
| case FOCUS_MODE_EDOF: |
| default: |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, m_curCameraInfo->focusMode); |
| return false; |
| break; |
| } |
| |
| m_flagAutoFocusRunning = false; |
| |
| return true; |
| } |
| |
| int ExynosCamera::getFucusModeResult(void) |
| { |
| int ret = 0; |
| |
| #define AF_WATING_TIME (100000) // 100msec |
| #define TOTAL_AF_WATING_TIME (2000000) // 2000msec |
| |
| for (unsigned int i = 0; i < TOTAL_AF_WATING_TIME; i += AF_WATING_TIME) { |
| |
| if (m_flagAutoFocusRunning == false) |
| return -1; |
| |
| if (exynos_v4l2_g_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT, &ret) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_g_ctrl() fail", __func__); |
| return -1; |
| } |
| |
| if (strcmp((const char*)m_cameraName, "S5K4E5") == 0) { |
| switch(ret) { |
| case 0x00: // AF Running |
| ret = 0; |
| break; |
| case 0x02: // AF succeed |
| ret = 1; |
| break; |
| case 0x01: |
| default : // AF fail |
| ret = -1; |
| break; |
| } |
| |
| if (ret != 0) |
| break; |
| |
| } else if (strcmp((const char*)m_cameraName, "M5M0") == 0) { |
| switch(ret) { |
| case 0x00: // AF Running |
| ret = 0; |
| break; |
| case 0x01: // AF succeed |
| ret = 1; |
| break; |
| case 0x02: // AF cancel |
| ret = 0; |
| break; |
| default: // AF fail |
| ret = -1; |
| break; |
| } |
| |
| if (ret != 0) |
| break; |
| } else { |
| ret = -1; |
| break; |
| } |
| |
| usleep(AF_WATING_TIME); |
| } |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::startFaceDetection(void) |
| { |
| if (m_flagStartFaceDetection == true) { |
| ALOGD("DEBUG(%s):Face detection already started..", __func__); |
| return true; |
| } |
| |
| if (m_previewDev->flagStart == true) { |
| //if (this->setFocusMode(FOCUS_MODE_AUTO) == false) |
| // ALOGE("ERR(%s):Fail setFocusMode", __func__); |
| |
| if (m_internalISP == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_FD_SET_MAX_FACE_NUMBER, m_defaultCameraInfo->maxNumDetectedFaces) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_START) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } else { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACE_DETECTION, FACE_DETECTION_ON) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| m_flagStartFaceDetection = true; |
| } |
| return true; |
| } |
| |
| bool ExynosCamera::stopFaceDetection(void) |
| { |
| if (m_flagStartFaceDetection == false) { |
| ALOGD("DEBUG(%s):Face detection already stopped..", __func__); |
| return true; |
| } |
| |
| if (m_previewDev->flagStart == true) { |
| if (m_internalISP == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_STOP) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } else { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACE_DETECTION, FACE_DETECTION_OFF) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| m_flagStartFaceDetection = false; |
| } |
| return true; |
| } |
| |
| bool ExynosCamera::flagStartFaceDetection(void) |
| { |
| return m_flagStartFaceDetection; |
| } |
| |
| bool ExynosCamera::setFaceDetectLock(bool toggle) |
| { |
| int lock = (toggle == true) ? 1 : 0; |
| |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, lock) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| return true; |
| } |
| |
| bool ExynosCamera::startSmoothZoom(int value) |
| { |
| if (m_defaultCameraInfo->hwZoomSupported == false) { |
| ALOGE("ERR(%s):m_defaultCameraInfo->hwZoomSupported == false", __func__); |
| return false; |
| } |
| |
| return this->setZoom(value); |
| } |
| |
| bool ExynosCamera::stopSmoothZoom(void) |
| { |
| // TODO |
| return true; |
| } |
| |
| int ExynosCamera::getAntibanding(void) |
| { |
| return m_curCameraInfo->antiBanding; |
| } |
| |
| bool ExynosCamera::getAutoExposureLock(void) |
| { |
| return m_curCameraInfo->autoExposureLock; |
| } |
| |
| bool ExynosCamera::getAutoWhiteBalanceLock(void) |
| { |
| return m_curCameraInfo->autoWhiteBalanceLock; |
| } |
| |
| int ExynosCamera::getColorEffect(void) |
| { |
| return m_curCameraInfo->effect; |
| } |
| |
| int ExynosCamera::getDetectedFacesAreas(int num, |
| int *id, |
| int *score, |
| ExynosRect *face, |
| ExynosRect *leftEye, |
| ExynosRect *rightEye, |
| ExynosRect *mouth) |
| { |
| if (m_defaultCameraInfo->maxNumDetectedFaces == 0) { |
| ALOGE("ERR(%s):maxNumDetectedFaces == 0 fail", __func__); |
| return -1; |
| } |
| |
| if (m_flagStartFaceDetection == false) { |
| ALOGD("DEBUG(%s):m_flagStartFaceDetection == false", __func__); |
| return 0; |
| } |
| |
| if (m_defaultCameraInfo->maxNumDetectedFaces < num) |
| num = m_defaultCameraInfo->maxNumDetectedFaces; |
| |
| // width : 0 ~ previewW |
| // height : 0 ~ previewH |
| // if eye, mouth is not detectable : -1, -1 |
| ExynosRect2 *face2 = new ExynosRect2[num]; |
| ExynosRect2 *leftEye2 = new ExynosRect2[num]; |
| ExynosRect2 *rightEye2 = new ExynosRect2[num]; |
| ExynosRect2 *mouth2 = new ExynosRect2[num]; |
| |
| num = getDetectedFacesAreas(num, id, score, face2, leftEye2, rightEye2, mouth2); |
| |
| for (int i = 0; i < num; i++) { |
| |
| m_secRect22SecRect(&face2[i], &face[i]); |
| face[i].fullW = m_curCameraInfo->previewW; |
| face[i].fullH = m_curCameraInfo->previewH; |
| |
| m_secRect22SecRect(&leftEye2[i], &leftEye[i]); |
| leftEye[i].fullW = m_curCameraInfo->previewW; |
| leftEye[i].fullH = m_curCameraInfo->previewH; |
| |
| m_secRect22SecRect(&rightEye2[i], &rightEye[i]); |
| rightEye[i].fullW = m_curCameraInfo->previewW; |
| rightEye[i].fullH = m_curCameraInfo->previewH; |
| |
| m_secRect22SecRect(&mouth2[i], &mouth[i]); |
| mouth[i].fullW = m_curCameraInfo->previewW; |
| mouth[i].fullH = m_curCameraInfo->previewH; |
| } |
| |
| delete [] face2; |
| delete [] leftEye2; |
| delete [] rightEye2; |
| delete [] mouth2; |
| |
| return num; |
| } |
| |
| int ExynosCamera::getDetectedFacesAreas(int num, |
| int *id, |
| int *score, |
| ExynosRect2 *face, |
| ExynosRect2 *leftEye, |
| ExynosRect2 *rightEye, |
| ExynosRect2 *mouth) |
| { |
| if (m_defaultCameraInfo->maxNumDetectedFaces == 0) { |
| ALOGE("ERR(%s):maxNumDetectedFaces == 0 fail", __func__); |
| return -1; |
| } |
| |
| if (m_flagStartFaceDetection == false) { |
| ALOGD("DEBUG(%s):m_flagStartFaceDetection == false", __func__); |
| return 0; |
| } |
| |
| int i = 0; |
| |
| if (m_defaultCameraInfo->maxNumDetectedFaces < num) |
| num = m_defaultCameraInfo->maxNumDetectedFaces; |
| |
| const unsigned int numOfFDEntity = 1 + ((V4L2_CID_IS_FD_GET_NEXT - V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER) * num); |
| |
| // width : 0 ~ previewW |
| // height : 0 ~ previewH |
| // if eye, mouth is not detectable : -1, -1 |
| struct v4l2_ext_controls fd_ctrls; |
| struct v4l2_ext_control *fd_ctrl = new struct v4l2_ext_control[numOfFDEntity]; |
| struct v4l2_ext_control *cur_ctrl; |
| |
| cur_ctrl = &fd_ctrl[0]; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_COUNT; |
| cur_ctrl++; |
| |
| for (i = 0; i < num; i++) { |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_CONFIDENCE; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y; |
| cur_ctrl++; |
| cur_ctrl->id = V4L2_CID_IS_FD_GET_NEXT; |
| cur_ctrl++; |
| } |
| |
| fd_ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; |
| fd_ctrls.count = i + 1; |
| fd_ctrls.controls = fd_ctrl; |
| |
| if (exynos_v4l2_g_ext_ctrl(m_previewDev->fd, &fd_ctrls) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_g_ext_ctrl() fail", __func__); |
| num = -1; |
| goto done; |
| } |
| |
| cur_ctrl = &fd_ctrl[0]; |
| num = cur_ctrl->value; |
| cur_ctrl++; |
| |
| for (i = 0; i < num; i++) { |
| id[i] = cur_ctrl->value; |
| cur_ctrl++; |
| score[i] = cur_ctrl->value; |
| cur_ctrl++; |
| |
| face[i].x1 = cur_ctrl->value; |
| cur_ctrl++; |
| face[i].y1 = cur_ctrl->value; |
| cur_ctrl++; |
| face[i].x2 = cur_ctrl->value; |
| cur_ctrl++; |
| face[i].y2 = cur_ctrl->value; |
| cur_ctrl++; |
| |
| leftEye[i].x1 = cur_ctrl->value; |
| cur_ctrl++; |
| leftEye[i].y1 = cur_ctrl->value; |
| cur_ctrl++; |
| leftEye[i].x2 = cur_ctrl->value; |
| cur_ctrl++; |
| leftEye[i].y2 = cur_ctrl->value; |
| cur_ctrl++; |
| |
| rightEye[i].x1 = cur_ctrl->value; |
| cur_ctrl++; |
| rightEye[i].y1 = cur_ctrl->value; |
| cur_ctrl++; |
| rightEye[i].x2 = cur_ctrl->value; |
| cur_ctrl++; |
| rightEye[i].y2 = cur_ctrl->value; |
| cur_ctrl++; |
| |
| mouth[i].x1 = cur_ctrl->value; |
| cur_ctrl++; |
| mouth[i].y1 = cur_ctrl->value; |
| cur_ctrl++; |
| mouth[i].x2 = cur_ctrl->value; |
| cur_ctrl++; |
| mouth[i].y2 = cur_ctrl->value; |
| cur_ctrl++; |
| } |
| |
| done: |
| delete [] fd_ctrl; |
| |
| return num; |
| } |
| |
| int ExynosCamera::getExposureCompensation(void) |
| { |
| return m_curCameraInfo->exposure; |
| } |
| |
| float ExynosCamera::getExposureCompensationStep(void) |
| { |
| // CameraParameters.h |
| // The exposure compensation step. Exposure compensation index multiply by |
| // step eqals to EV. Ex: if exposure compensation index is 6 and step is |
| // 0.3333, EV is -2. |
| // Example value: "0.333333333" or "0.5". Read only. |
| // -> But, this formula doesn't works in apps. |
| return 1.0f; |
| } |
| |
| int ExynosCamera::getFlashMode(void) |
| { |
| return m_curCameraInfo->flashMode; |
| } |
| |
| bool ExynosCamera::getFocalLength(int *num, int *den) |
| { |
| *num = m_defaultCameraInfo->focalLengthNum; |
| *num = m_defaultCameraInfo->focalLengthDen; |
| return true; |
| } |
| |
| int ExynosCamera::getFocusAreas(ExynosRect *rects) |
| { |
| // TODO |
| return 0; |
| } |
| |
| int ExynosCamera::getFocusDistances(float *output) |
| { |
| // TODO |
| return 0; |
| } |
| |
| int ExynosCamera::getFocusMode(void) |
| { |
| return m_curCameraInfo->focusMode; |
| } |
| |
| float ExynosCamera::getHorizontalViewAngle(void) |
| { |
| //TODO |
| return 51.2f; |
| } |
| |
| int ExynosCamera::getJpegQuality(void) |
| { |
| return m_jpegQuality; |
| } |
| |
| int ExynosCamera::getJpegThumbnailQuality(void) |
| { |
| return m_jpegThumbnailQuality; |
| } |
| |
| bool ExynosCamera::getJpegThumbnailSize(int *w, int *h) |
| { |
| *w = m_curCameraInfo->thumbnailW; |
| *h = m_curCameraInfo->thumbnailH; |
| return true; |
| } |
| |
| int ExynosCamera::getMaxExposureCompensation(void) |
| { |
| return m_defaultCameraInfo->maxExposure; |
| } |
| |
| int ExynosCamera::getMaxNumDetectedFaces(void) |
| { |
| return m_defaultCameraInfo->maxNumDetectedFaces; |
| } |
| |
| int ExynosCamera::getMaxNumFocusAreas(void) |
| { |
| return m_defaultCameraInfo->maxNumFocusAreas; |
| } |
| |
| int ExynosCamera::getMaxNumMeteringAreas(void) |
| { |
| return m_defaultCameraInfo->maxNumMeteringAreas; |
| } |
| |
| int ExynosCamera::getMaxZoom(void) |
| { |
| return m_defaultCameraInfo->maxZoom; |
| } |
| |
| int ExynosCamera::getMeteringAreas(ExynosRect *rects) |
| { |
| // TODO |
| return 0; |
| } |
| |
| int ExynosCamera::getMinExposureCompensation(void) |
| { |
| return m_defaultCameraInfo->minExposure; |
| } |
| |
| int ExynosCamera::getPictureFormat(void) |
| { |
| return m_curCameraInfo->pictureColorFormat; |
| } |
| |
| bool ExynosCamera::getPictureSize(int *w, int *h) |
| { |
| *w = m_curCameraInfo->pictureW; |
| *h = m_curCameraInfo->pictureH; |
| return true; |
| } |
| |
| int ExynosCamera::getPreviewFormat(void) |
| { |
| return m_curCameraInfo->previewColorFormat; |
| } |
| |
| bool ExynosCamera::getPreviewFpsRange(int *min, int *max) |
| { |
| *min = 1; |
| *max = m_defaultCameraInfo->fps; |
| return true; |
| } |
| |
| int ExynosCamera::getPreviewFrameRate(void) |
| { |
| return m_curCameraInfo->fps; |
| } |
| |
| bool ExynosCamera::getPreviewSize(int *w, int *h) |
| { |
| *w = m_curCameraInfo->previewW; |
| *h = m_curCameraInfo->previewH; |
| return true; |
| } |
| |
| int ExynosCamera::getSceneMode(void) |
| { |
| return m_curCameraInfo->sceneMode; |
| } |
| |
| int ExynosCamera::getSupportedAntibanding(void) |
| { |
| return m_defaultCameraInfo->antiBandingList; |
| } |
| |
| int ExynosCamera::getSupportedColorEffects(void) |
| { |
| return m_defaultCameraInfo->effectList; |
| } |
| |
| int ExynosCamera::getSupportedFlashModes(void) |
| { |
| return m_defaultCameraInfo->flashModeList; |
| } |
| |
| int ExynosCamera::getSupportedFocusModes(void) |
| { |
| return m_defaultCameraInfo->focusModeList; |
| } |
| |
| bool ExynosCamera::getSupportedJpegThumbnailSizes(int *w, int *h) |
| { |
| *w = m_defaultCameraInfo->thumbnailW; |
| *h = m_defaultCameraInfo->thumbnailH; |
| return true; |
| } |
| |
| bool ExynosCamera::getSupportedPictureSizes(int *w, int *h) |
| { |
| *w = m_defaultCameraInfo->pictureW; |
| *h = m_defaultCameraInfo->pictureH; |
| return true; |
| } |
| |
| bool ExynosCamera::getSupportedPreviewSizes(int *w, int *h) |
| { |
| *w = m_defaultCameraInfo->previewW; |
| *h = m_defaultCameraInfo->previewH; |
| return true; |
| } |
| |
| int ExynosCamera::getSupportedSceneModes(void) |
| { |
| return m_defaultCameraInfo->sceneModeList; |
| } |
| |
| bool ExynosCamera::getSupportedVideoSizes(int *w, int *h) |
| { |
| *w = m_defaultCameraInfo->videoW; |
| *h = m_defaultCameraInfo->videoH; |
| return true; |
| } |
| |
| bool ExynosCamera::getPreferredPreivewSizeForVideo(int *w, int *h) |
| { |
| *w = m_defaultCameraInfo->prefVideoPreviewW; |
| *h = m_defaultCameraInfo->prefVideoPreviewH; |
| return true; |
| } |
| |
| int ExynosCamera::getSupportedWhiteBalance(void) |
| { |
| return m_defaultCameraInfo->whiteBalanceList; |
| } |
| |
| float ExynosCamera::getVerticalViewAngle(void) |
| { |
| // TODO |
| return 39.4f; |
| } |
| |
| bool ExynosCamera::getVideoStabilization(void) |
| { |
| return m_curCameraInfo->videoStabilization; |
| } |
| |
| int ExynosCamera::getWhiteBalance(void) |
| { |
| return m_curCameraInfo->whiteBalance; |
| } |
| |
| int ExynosCamera::getZoom(void) |
| { |
| return m_curCameraInfo->zoom; |
| } |
| |
| int ExynosCamera::getMaxZoomRatio(void) |
| { |
| return 400; |
| } |
| |
| bool ExynosCamera::isAutoExposureLockSupported(void) |
| { |
| return m_defaultCameraInfo->autoExposureLockSupported; |
| } |
| |
| bool ExynosCamera::isAutoWhiteBalanceLockSupported(void) |
| { |
| return m_defaultCameraInfo->autoWhiteBalanceLockSupported; |
| } |
| |
| bool ExynosCamera::isSmoothZoomSupported(void) |
| { |
| if (m_defaultCameraInfo->hwZoomSupported == true) |
| return true; |
| else |
| return false; |
| } |
| |
| bool ExynosCamera::isVideoSnapshotSupported(void) |
| { |
| return true; |
| } |
| |
| bool ExynosCamera::isVideoStabilizationSupported(void) |
| { |
| return m_defaultCameraInfo->supportVideoStabilization; |
| } |
| |
| bool ExynosCamera::isZoomSupported(void) |
| { |
| return true; |
| } |
| |
| bool ExynosCamera::setAntibanding(int value) |
| { |
| int internalValue = -1; |
| |
| switch (value) { |
| case ANTIBANDING_AUTO: |
| internalValue = ::ANTI_BANDING_AUTO; |
| break; |
| case ANTIBANDING_50HZ: |
| internalValue = ::ANTI_BANDING_50HZ; |
| break; |
| case ANTIBANDING_60HZ: |
| internalValue = ::ANTI_BANDING_60HZ; |
| break; |
| case ANTIBANDING_OFF: |
| internalValue = ::ANTI_BANDING_OFF; |
| break; |
| default: |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, value); |
| return false; |
| break; |
| } |
| |
| if (m_internalISP == true) { |
| if (internalValue < ::IS_AFC_DISABLE || ::IS_AFC_MAX <= internalValue) { |
| ALOGE("ERR(%s):Invalid value (%d)", __func__, value); |
| return false; |
| } |
| } else { |
| if (internalValue < ::ANTI_BANDING_AUTO || ::ANTI_BANDING_OFF < internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue); |
| return false; |
| } |
| } |
| |
| if (m_curCameraInfo->antiBanding != value) { |
| m_curCameraInfo->antiBanding = value; |
| if (m_flagCreate == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_AFC_MODE, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setAutoExposureLock(bool toggle) |
| { |
| int internalValue = -1; |
| |
| if (m_curCameraInfo->autoExposureLock == toggle) |
| return true; |
| |
| m_curCameraInfo->autoExposureLock = toggle; |
| |
| if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == true) |
| internalValue = AE_LOCK_AWB_LOCK; |
| else if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == false) |
| internalValue = AE_LOCK_AWB_UNLOCK; |
| else if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == true) |
| internalValue = AE_UNLOCK_AWB_LOCK; |
| else // if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == false) |
| internalValue = AE_UNLOCK_AWB_UNLOCK; |
| |
| if (m_flagCreate == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool ExynosCamera::setAutoWhiteBalanceLock(bool toggle) |
| { |
| int internalValue = -1; |
| |
| if (m_curCameraInfo->autoWhiteBalanceLock == toggle) |
| return true; |
| |
| m_curCameraInfo->autoWhiteBalanceLock = toggle; |
| |
| if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == true) |
| internalValue = AE_LOCK_AWB_LOCK; |
| else if (m_curCameraInfo->autoExposureLock == true && m_curCameraInfo->autoWhiteBalanceLock == false) |
| internalValue = AE_LOCK_AWB_UNLOCK; |
| else if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == true) |
| internalValue = AE_UNLOCK_AWB_LOCK; |
| else // if (m_curCameraInfo->autoExposureLock == false && m_curCameraInfo->autoWhiteBalanceLock == false) |
| internalValue = AE_UNLOCK_AWB_UNLOCK; |
| |
| if (m_flagCreate == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool ExynosCamera::setColorEffect(int value) |
| { |
| int internalValue = -1; |
| |
| switch (value) { |
| case EFFECT_NONE: |
| if (m_internalISP == true) |
| internalValue = ::IS_IMAGE_EFFECT_DISABLE; |
| else |
| internalValue = ::IMAGE_EFFECT_NONE; |
| break; |
| case EFFECT_MONO: |
| if (m_internalISP == true) |
| internalValue = ::IS_IMAGE_EFFECT_MONOCHROME; |
| else |
| internalValue = ::IMAGE_EFFECT_BNW; |
| break; |
| case EFFECT_NEGATIVE: |
| internalValue = IS_IMAGE_EFFECT_NEGATIVE_MONO; |
| break; |
| case EFFECT_SEPIA: |
| if (m_internalISP == true) |
| internalValue = ::IS_IMAGE_EFFECT_SEPIA; |
| else |
| internalValue = ::IMAGE_EFFECT_SEPIA; |
| break; |
| case EFFECT_AQUA: |
| case EFFECT_SOLARIZE: |
| case EFFECT_POSTERIZE: |
| case EFFECT_WHITEBOARD: |
| case EFFECT_BLACKBOARD: |
| default: |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, value); |
| return false; |
| break; |
| } |
| |
| if (m_internalISP == true) { |
| if (internalValue < ::IS_IMAGE_EFFECT_DISABLE || ::IS_IMAGE_EFFECT_MAX <= internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue); |
| return false; |
| } |
| } else { |
| if (internalValue <= ::IMAGE_EFFECT_BASE || ::IMAGE_EFFECT_MAX <= internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue); |
| return false; |
| } |
| } |
| |
| if (m_curCameraInfo->effect != value) { |
| m_curCameraInfo->effect = value; |
| if (m_flagCreate == true) { |
| if (m_internalISP == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_IMAGE_EFFECT, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } else { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_EFFECT, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setExposureCompensation(int value) |
| { |
| int internalValue = value; |
| |
| if (m_internalISP == true) { |
| internalValue += IS_EXPOSURE_DEFAULT; |
| if (internalValue < IS_EXPOSURE_MINUS_2 || IS_EXPOSURE_PLUS_2 < internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue); |
| return false; |
| } |
| } else { |
| internalValue += EV_DEFAULT; |
| if (internalValue < EV_MINUS_4 || EV_PLUS_4 < internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue(%d)", __func__, internalValue); |
| return false; |
| } |
| } |
| |
| if (m_curCameraInfo->exposure != value) { |
| m_curCameraInfo->exposure = value; |
| if (m_flagCreate == true) { |
| if (m_internalISP == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_IS_CAMERA_EXPOSURE, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } else { |
| if (this->setBrightness(value) == false) { |
| ALOGE("ERR(%s):setBrightness() fail", __func__); |
| return false; |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setFlashMode(int value) |
| { |
| int internalValue = -1; |
| |
| switch (value) { |
| case FLASH_MODE_OFF: |
| internalValue = ::FLASH_MODE_OFF; |
| break; |
| case FLASH_MODE_AUTO: |
| internalValue = ::FLASH_MODE_AUTO; |
| break; |
| case FLASH_MODE_ON: |
| internalValue = ::FLASH_MODE_ON; |
| break; |
| case FLASH_MODE_TORCH: |
| internalValue = ::FLASH_MODE_TORCH; |
| break; |
| case FLASH_MODE_RED_EYE: |
| default: |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, value); |
| return false; |
| break; |
| } |
| |
| if (internalValue <= ::FLASH_MODE_BASE || ::FLASH_MODE_MAX <= internalValue) { |
| ALOGE("ERR(%s):Invalid value (%d)", __func__, value); |
| return false; |
| } |
| |
| if (m_curCameraInfo->flashMode != value) { |
| m_curCameraInfo->flashMode = value; |
| if (m_flagCreate == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FLASH_MODE, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setFocusAreas(int num, ExynosRect* rects, int *weights) |
| { |
| if (m_defaultCameraInfo->maxNumFocusAreas == 0) { |
| ALOGV("DEBUG(%s):maxNumFocusAreas is 0. so, ignored", __func__); |
| return true; |
| } |
| |
| bool ret = true; |
| |
| ExynosRect2 *rect2s = new ExynosRect2[num]; |
| for (int i = 0; i < num; i++) |
| m_secRect2SecRect2(&rects[i], &rect2s[i]); |
| |
| ret = setFocusAreas(num, rect2s, weights); |
| |
| delete [] rect2s; |
| |
| return ret; |
| } |
| |
| bool ExynosCamera::setFocusAreas(int num, ExynosRect2* rect2s, int *weights) |
| { |
| if (m_defaultCameraInfo->maxNumFocusAreas == 0) { |
| ALOGV("DEBUG(%s):maxNumFocusAreas is 0. so, ignored", __func__); |
| return true; |
| } |
| |
| int new_x = 0; |
| int new_y = 0; |
| |
| if (m_defaultCameraInfo->maxNumFocusAreas < num) |
| num = m_defaultCameraInfo->maxNumFocusAreas; |
| |
| if (m_flagCreate == true) { |
| for (int i = 0; i < num; i++) { |
| if ( num == 1 |
| && rect2s[0].x1 == 0 |
| && rect2s[0].y1 == 0 |
| && rect2s[0].x2 == m_curCameraInfo->previewW |
| && rect2s[0].y2 == m_curCameraInfo->previewH) { |
| // TODO : driver decide focus areas -> focus center. |
| new_x = (m_curCameraInfo->previewW) / 2; |
| new_y = (m_curCameraInfo->previewH) / 2; |
| } else { |
| new_x = (rect2s[i].x1 + rect2s[i].x2) / 2; |
| new_y = (rect2s[i].y1 + rect2s[i].y2) / 2; |
| } |
| |
| m_touchAFMode = true; |
| if ( exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, new_x) < 0 |
| && exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, new_y) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setFocusMode(int value) |
| { |
| int internalValue = -1; |
| |
| switch (value) { |
| case FOCUS_MODE_AUTO: |
| internalValue = ::FOCUS_MODE_AUTO; |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_INFINITY: |
| internalValue = ::FOCUS_MODE_INFINITY; |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_MACRO: |
| internalValue = ::FOCUS_MODE_MACRO; |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_CONTINUOUS_VIDEO: |
| case FOCUS_MODE_CONTINUOUS_PICTURE: |
| internalValue = ::FOCUS_MODE_CONTINOUS; |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_TOUCH: |
| internalValue = ::FOCUS_MODE_TOUCH; |
| m_touchAFMode = true; |
| break; |
| case FOCUS_MODE_FIXED: |
| internalValue = ::FOCUS_MODE_FIXED; |
| m_touchAFMode = false; |
| break; |
| case FOCUS_MODE_EDOF: |
| default: |
| m_touchAFMode = false; |
| ALOGE("ERR(%s):Unsupported value(%d)", __func__, value); |
| return false; |
| break; |
| } |
| |
| if (::FOCUS_MODE_MAX <= internalValue) { |
| ALOGE("ERR(%s):Invalid internalValue (%d)", __func__, internalValue); |
| return false; |
| } |
| |
| if (m_curCameraInfo->focusMode != value) { |
| m_curCameraInfo->focusMode = value; |
| if (m_flagCreate == true) { |
| if (exynos_v4l2_s_ctrl(m_previewDev->fd, V4L2_CID_CAMERA_FOCUS_MODE, internalValue) < 0) { |
| ALOGE("ERR(%s):exynos_v4l2_s_ctrl() fail", __func__); |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setGpsAltitude(const char *gpsAltitude) |
| { |
| double conveted_altitude = 0; |
| |
| if (gpsAltitude == NULL) |
| m_curCameraInfo->gpsAltitude = 0; |
| else { |
| conveted_altitude = atof(gpsAltitude); |
| m_curCameraInfo->gpsAltitude = (long)(conveted_altitude * 100 / 1); |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setGpsLatitude(const char *gpsLatitude) |
| { |
| double conveted_latitude = 0; |
| |
| if (gpsLatitude == NULL) |
| m_curCameraInfo->gpsLatitude = 0; |
| else { |
| conveted_latitude = atof(gpsLatitude); |
| m_curCameraInfo->gpsLatitude = (long)(conveted_latitude * 10000 / 1); |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setGpsLongitude(const char *gpsLongitude) |
| { |
| double conveted_longitude = 0; |
| |
| if (gpsLongitude == NULL) |
| m_curCameraInfo->gpsLongitude = 0; |
| else { |
| conveted_longitude = atof(gpsLongitude); |
| m_curCameraInfo->gpsLongitude = (long)(conveted_longitude * 10000 / 1); |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setGpsProcessingMethod(const char *gpsProcessingMethod) |
| { |
| memset(mExifInfo.gps_processing_method, 0, sizeof(mExifInfo.gps_processing_method)); |
| |
| if (gpsProcessingMethod != NULL) { |
| size_t len = strlen(gpsProcessingMethod); |
| if (len > sizeof(mExifInfo.gps_processing_method)) { |
| len = sizeof(mExifInfo.gps_processing_method); |
| } |
| memcpy(mExifInfo.gps_processing_method, gpsProcessingMethod, len); |
| } |
| |
| return true; |
| } |
| |
| bool ExynosCamera::setGpsTimeStamp(const char *gpsTimestamp) |
| { |
| if (gpsTimestamp == NULL) |
| m_curCameraInfo->gpsTimestamp = 0; |
| else |
| m_curCameraInfo->gpsTimestamp = atol(gpsTimestamp); |
|