blob: 0485aa9708ea139e2dc62c35dce30bb4a52a78ab [file] [log] [blame]
/*
* 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(gpsTimest