diff options
Diffstat (limited to 'libcamera')
-rw-r--r-- | libcamera/Android.mk | 45 | ||||
-rw-r--r-- | libcamera/SecCamera.cpp | 3932 | ||||
-rw-r--r-- | libcamera/SecCamera.h | 886 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.cpp | 2370 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.h | 257 |
5 files changed, 7490 insertions, 0 deletions
diff --git a/libcamera/Android.mk b/libcamera/Android.mk new file mode 100644 index 0000000..192af24 --- /dev/null +++ b/libcamera/Android.mk @@ -0,0 +1,45 @@ +# When zero we link against libqcamera; when 1, we dlopen libqcamera. +ifeq ($(BOARD_CAMERA_LIBRARIES),libcamera) + +DLOPEN_LIBSECCAMERA:=1 + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_CFLAGS:=-fno-short-enums +LOCAL_CFLAGS+=-DDLOPEN_LIBSECCAMERA=$(DLOPEN_LIBSECCAMERA) +LOCAL_CFLAGS += -DSWP1_CAMERA_ADD_ADVANCED_FUNCTION + + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs3cjpeg + + +LOCAL_SRC_FILES:= \ + SecCamera.cpp \ + SecCameraHWInterface.cpp + + +LOCAL_SHARED_LIBRARIES:= libutils libui liblog libbinder libcutils +LOCAL_SHARED_LIBRARIES+= libs3cjpeg +LOCAL_SHARED_LIBRARIES+= libcamera_client + +#Enable the below code to show the video output (without GUI) on TV +#ifeq ($(BOARD_USES_HDMI), true) +#LOCAL_CFLAGS+=-DENABLE_HDMI_DISPLAY \ +# -DBOARD_HDMI_STD=$(BOARD_HDMI_STD) +# +#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include +#LOCAL_SHARED_LIBRARIES+= libhdmi +#endif + +ifeq ($(DLOPEN_LIBSECCAMERA),1) +LOCAL_SHARED_LIBRARIES+= libdl +endif + +LOCAL_MODULE:= libcamera + +include $(BUILD_SHARED_LIBRARY) + +endif + diff --git a/libcamera/SecCamera.cpp b/libcamera/SecCamera.cpp new file mode 100644 index 0000000..186421e --- /dev/null +++ b/libcamera/SecCamera.cpp @@ -0,0 +1,3932 @@ +/* + * Copyright@ 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 on 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. + */ + +/* +************************************ +* Filename: SecCamera.cpp +* Author: Sachin P. Kamat +* Purpose: This file interacts with the Camera and JPEG drivers. +************************************* +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SecCamera" +#define ADD_THUMB_IMG 1 + +#include <utils/Log.h> + +#include <string.h> +#include <stdlib.h> +#include <sys/poll.h> +#include "SecCamera.h" +#include "cutils/properties.h" + +#ifdef BOARD_USES_SDTV +#include "TvOut.h" +#endif + +using namespace android; + +#ifdef BOARD_USES_SDTV +#include "utils/Timers.h" +//#define MEASURE_DURATION_TVOUT +sp<TvOut> mtvoutcamera; +static bool suspendTvInit = false ; +#define TVOUT_RESUME_TIME 4 +#endif + +//#define PERFORMANCE //Uncomment to measure performance +//#define DUMP_YUV //Uncomment to take a dump of YUV frame during capture + +#define CHECK(return_value) \ + if(return_value < 0) \ + { \ + LOGE("%s::%d fail. errno: %s\n", __func__,__LINE__, strerror(errno)); \ + return -1; \ + } \ + +#define CHECK_PTR(return_value) \ + if(return_value < 0) \ + { \ + LOGE("%s::%d fail\n", __func__,__LINE__); \ + return NULL; \ + } \ + +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) + +namespace android { + +// ====================================================================== +// Camera controls + +static struct timeval time_start; +static struct timeval time_stop; +static int cam_id = 0; + +unsigned long measure_time(struct timeval *start, struct timeval *stop) +{ + + unsigned long sec, usec, time; + + sec = stop->tv_sec - start->tv_sec; + + if (stop->tv_usec >= start->tv_usec) { + usec = stop->tv_usec - start->tv_usec; + } else { + usec = stop->tv_usec + 1000000 - start->tv_usec; + sec--; + } + + time = (sec * 1000000) + usec; + + return time; +} + +static inline unsigned long check_performance() +{ + unsigned long time = 0; + static unsigned long max=0, min=0xffffffff; + + if(time_start.tv_sec == 0 && time_start.tv_usec == 0) { + gettimeofday(&time_start, NULL); + } else { + gettimeofday(&time_stop, NULL); + time = measure_time(&time_start, &time_stop); + if(max < time) max = time; + if(min > time) min = time; + LOGV("Interval: %lu us (%2.2lf fps), min:%2.2lf fps, max:%2.2lf fps\n", time, 1000000.0/time, 1000000.0/max, 1000000.0/min); + gettimeofday(&time_start, NULL); + } + + return time; +} + +static int close_buffers(struct fimc_buffer *buffers) +{ + int i; + + for (i = 0; i < MAX_BUFFERS; i++) { + if (buffers[i].start) + { + munmap(buffers[i].start, buffers[i].length); + //LOGV("munmap():virt. addr[%d]: 0x%x size = %d\n", i, (unsigned int) buffers[i].start, buffers[i].length); + buffers[i].start = NULL; + } + } + + return 0; +} + +static int get_pixel_depth(unsigned int fmt) +{ + int depth = 0; + + switch (fmt) { + case V4L2_PIX_FMT_NV12: + depth = 12; + break; + case V4L2_PIX_FMT_NV12T: + depth = 12; + break; + case V4L2_PIX_FMT_NV21: + depth = 12; + break; + case V4L2_PIX_FMT_YUV420: + depth = 12; + break; + + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUV422P: + depth = 16; + break; + + case V4L2_PIX_FMT_RGB32: + depth = 32; + break; + } + + return depth; +} + +#define ALIGN_W(x) ((x+0x7F)&(~0x7F)) // Set as multiple of 128 +#define ALIGN_H(x) ((x+0x1F)&(~0x1F)) // Set as multiple of 32 +#define ALIGN_BUF(x) ((x+0x1FFF)&(~0x1FFF)) // Set as multiple of 8K + +static int init_yuv_buffers(struct fimc_buffer *buffers, int width, int height, unsigned int fmt) +{ + int i, len; + + len = (width * height * get_pixel_depth(fmt)) / 8; + + + for (i = 0; i < MAX_BUFFERS; i++) + { + if(fmt==V4L2_PIX_FMT_NV12T) + { + buffers[i].start = NULL; + buffers[i].length = ALIGN_BUF(ALIGN_W(width) * ALIGN_H(height))+ ALIGN_BUF(ALIGN_W(width) * ALIGN_H(height/2)); + } + else + { + buffers[i].start = NULL; + buffers[i].length = len; + } + } + + return 0; +} + +static int fimc_poll(struct pollfd *events) +{ + int ret; + + ret = poll(events, 1, 5000); + if (ret < 0) { + LOGE("ERR(%s):poll error\n", __FUNCTION__); + return ret; + } + + if (ret == 0) { + LOGE("ERR(%s):No data in 5 secs..\n", __FUNCTION__); + return ret; + } + + return ret; +} + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +static int fimc_esd_poll(struct pollfd *events) +{ + int ret; + + ret = poll(events, 1, 1000); + + if (ret < 0) { + LOGE("ERR(%s):poll error\n", __FUNCTION__); + return ret; + } + + if (ret == 0) { + LOGE("ERR(%s):No data in 1 secs.. Camera Device Reset \n", __FUNCTION__); + return ret; + } + + return ret; +} +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + +#ifdef DUMP_YUV +static int save_yuv(struct fimc_buffer *m_buffers_c, int width, int height, int depth, int index, int frame_count) +{ + FILE *yuv_fp = NULL; + char filename[100], *buffer = NULL; + + /* file create/open, note to "wb" */ + yuv_fp = fopen("/sdcard/camera_dump.yuv", "wb"); + if (yuv_fp==NULL) + { + LOGE("Save YUV] file open error"); + return -1; + } + + buffer = (char *) malloc(m_buffers_c[index].length); + if(buffer == NULL) + { + LOGE("Save YUV] buffer alloc failed"); + if(yuv_fp) fclose(yuv_fp); + return -1; + } + + memcpy(buffer, m_buffers_c[index].start, m_buffers_c[index].length); + + fflush(stdout); + + fwrite(buffer, 1, m_buffers_c[index].length, yuv_fp); + + fflush(yuv_fp); + + if(yuv_fp) + fclose(yuv_fp); + if(buffer) + free(buffer); + + return 0; +} +#endif //DUMP_YUV + +static int fimc_v4l2_querycap(int fp) +{ + struct v4l2_capability cap; + int ret = 0; + + ret = ioctl(fp, VIDIOC_QUERYCAP, &cap); + + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_QUERYCAP failed\n", __FUNCTION__); + return -1; + } + + if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + LOGE("ERR(%s):no capture devices\n", __FUNCTION__); + return -1; + } + + return ret; +} + +static int fimc_v4l2_enuminput(int fp) +{ + struct v4l2_input input; + + input.index = cam_id; + if(ioctl(fp, VIDIOC_ENUMINPUT, &input) != 0) + { + LOGE("ERR(%s):No matching index found\n", __FUNCTION__); + return -1; + } + LOGI("Name of input channel[%d] is %s\n", input.index, input.name); + + return input.index; +} + + +static int fimc_v4l2_s_input(int fp, int index) +{ + struct v4l2_input input; + int ret; + + input.index = index; + + ret = ioctl(fp, VIDIOC_S_INPUT, &input); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_INPUT failed\n", __FUNCTION__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_s_fmt(int fp, int width, int height, unsigned int fmt, int flag_capture) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + int ret; + + v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + + pixfmt.sizeimage = (width * height * get_pixel_depth(fmt)) / 8; + + pixfmt.field = V4L2_FIELD_NONE; + + v4l2_fmt.fmt.pix = pixfmt; + + /* Set up for capture */ + ret = ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed\n", __FUNCTION__); + return -1; + } + + return 0; +} + +static int fimc_v4l2_s_fmt_cap(int fp, int width, int height, unsigned int fmt) +{ + struct v4l2_format v4l2_fmt; + struct v4l2_pix_format pixfmt; + int ret; + + memset(&pixfmt, 0, sizeof(pixfmt)); + + v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + pixfmt.width = width; + pixfmt.height = height; + pixfmt.pixelformat = fmt; + if (fmt == V4L2_PIX_FMT_JPEG){ + pixfmt.colorspace = V4L2_COLORSPACE_JPEG; + } + + pixfmt.sizeimage = (width * height * get_pixel_depth(fmt)) / 8; + + v4l2_fmt.fmt.pix = pixfmt; + + //LOGE("ori_w %d, ori_h %d, w %d, h %d\n", width, height, v4l2_fmt.fmt.pix.width, v4l2_fmt.fmt.pix.height); + + /* Set up for capture */ + ret = ioctl(fp, VIDIOC_S_FMT, &v4l2_fmt); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_FMT failed\n", __FUNCTION__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_enum_fmt(int fp, unsigned int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int found = 0; + + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmtdesc.index = 0; + + while (ioctl(fp, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { + if (fmtdesc.pixelformat == fmt) { + LOGD("passed fmt = %d found pixel format[%d]: %s\n", fmt, fmtdesc.index, fmtdesc.description); + found = 1; + break; + } + + fmtdesc.index++; + } + + if (!found) { + LOGE("unsupported pixel format\n"); + return -1; + } + + return 0; +} + +static int fimc_v4l2_reqbufs(int fp, enum v4l2_buf_type type, int nr_bufs) +{ + struct v4l2_requestbuffers req; + int ret; + + req.count = nr_bufs; + req.type = type; + req.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(fp, VIDIOC_REQBUFS, &req); + if(ret < 0) { + LOGE("ERR(%s):VIDIOC_REQBUFS failed\n", __FUNCTION__); + return -1; + } + + return req.count; +} + +static int fimc_v4l2_querybuf(int fp, struct fimc_buffer *buffers, enum v4l2_buf_type type, int nr_frames) +{ + struct v4l2_buffer v4l2_buf; + int i, ret; + + for(i = 0; i < nr_frames; i++) + { + v4l2_buf.type = type; + v4l2_buf.memory = V4L2_MEMORY_MMAP; + v4l2_buf.index = i; + + ret = ioctl(fp , VIDIOC_QUERYBUF, &v4l2_buf); + if(ret < 0) + { + LOGE("ERR(%s):VIDIOC_QUERYBUF failed\n", __FUNCTION__); + return -1; + } + + if(nr_frames == 1) + { + buffers[i].length = v4l2_buf.length; + if ((buffers[i].start = (char *) mmap(0, v4l2_buf.length, \ + PROT_READ | PROT_WRITE, MAP_SHARED, \ + fp, v4l2_buf.m.offset)) < 0) + { + LOGE("%s %d] mmap() failed\n",__FUNCTION__, __LINE__); + return -1; + } + + //LOGV("buffers[%d].start = %p v4l2_buf.length = %d", i, buffers[i].start, v4l2_buf.length); + } + else + { + +#if defined DUMP_YUV || defined (SEND_YUV_RECORD_DATA) + buffers[i].length = v4l2_buf.length; + if ((buffers[i].start = (char *) mmap(0, v4l2_buf.length, \ + PROT_READ | PROT_WRITE, MAP_SHARED, \ + fp, v4l2_buf.m.offset)) < 0) + { + LOGE("%s %d] mmap() failed\n",__FUNCTION__, __LINE__); + return -1; + } + + //LOGV("buffers[%d].start = %p v4l2_buf.length = %d", i, buffers[i].start, v4l2_buf.length); +#endif + } + + } + + return 0; +} + +static int fimc_v4l2_streamon(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int ret; + + ret = ioctl(fp, VIDIOC_STREAMON, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMON failed\n", __FUNCTION__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_streamoff(int fp) +{ + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int ret; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGE("%s()", __FUNCTION__); +#endif + ret = ioctl(fp, VIDIOC_STREAMOFF, &type); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_STREAMOFF failed\n", __FUNCTION__); + return ret; + } + + return ret; +} + +static int fimc_v4l2_qbuf(int fp, int index) +{ + struct v4l2_buffer v4l2_buf; + int ret; + + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buf.memory = V4L2_MEMORY_MMAP; + v4l2_buf.index = index; + + ret = ioctl(fp, VIDIOC_QBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_QBUF failed\n", __FUNCTION__); + return ret; + } + + return 0; +} + +static int fimc_v4l2_dqbuf(int fp) +{ + struct v4l2_buffer v4l2_buf; + int ret; + + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buf.memory = V4L2_MEMORY_MMAP; + + ret = ioctl(fp, VIDIOC_DQBUF, &v4l2_buf); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_DQBUF failed\n", __FUNCTION__); + return ret; + } + + return v4l2_buf.index; +} + +static int fimc_v4l2_g_ctrl(int fp, unsigned int id) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + + ret = ioctl(fp, VIDIOC_G_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_G_CTRL failed\n", __FUNCTION__); + return ret; + } + + return ctrl.value; +} + +static int fimc_v4l2_s_ctrl(int fp, unsigned int id, unsigned int value) +{ + struct v4l2_control ctrl; + int ret; + + ctrl.id = id; + ctrl.value = value; + + ret = ioctl(fp, VIDIOC_S_CTRL, &ctrl); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_CTRL failed, ret: %d\n", __FUNCTION__, ret); + return ret; + } + + return ctrl.value; +} + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +static int fimc_v4l2_s_ext_ctrl(int fp, unsigned int id, void * value) +{ + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + int ret; + + ctrl.id = id; + ctrl.reserved = value; + + ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ctrls.count = 1; + ctrls.controls = &ctrl; + + ret = ioctl(fp, VIDIOC_S_EXT_CTRLS, &ctrls); + if (ret < 0) + LOGE("ERR(%s):VIDIOC_S_EXT_CTRLS failed\n", __FUNCTION__); + + return ret; +} +#endif +static int fimc_v4l2_g_parm(int fp) +{ + struct v4l2_streamparm stream; + int ret; + + stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fp, VIDIOC_G_PARM, &stream); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_G_PARM failed\n", __FUNCTION__); + return -1; + } + +// LOGV("timeperframe: numerator %d, denominator %d\n", \ + stream.parm.capture.timeperframe.numerator, \ + stream.parm.capture.timeperframe.denominator); + + return 0; +} + +static int fimc_v4l2_s_parm(int fp, int fps_numerator, int fps_denominator) +{ + struct v4l2_streamparm stream; + int ret; + + stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + stream.parm.capture.capturemode = 0; + stream.parm.capture.timeperframe.numerator = fps_numerator; + stream.parm.capture.timeperframe.denominator = fps_denominator; + + ret = ioctl(fp, VIDIOC_S_PARM, &stream); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_PARM failed\n", __FUNCTION__); + return ret; + } + + return 0; +} + +#if 0 +static int fimc_v4l2_s_parm_ex(int fp, int mode, int no_dma_op) //Kamat: not present in new code +{ + struct v4l2_streamparm stream; + int ret; + + stream.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + stream.parm.capture.capturemode = mode; + if(no_dma_op) + stream.parm.capture.reserved[0] = 100; + + ret = ioctl(fp, VIDIOC_S_PARM, &stream); + if (ret < 0) { + LOGE("ERR(%s):VIDIOC_S_PARM_EX failed\n", __FUNCTION__); + return ret; + } + + return 0; +} +#endif + +// ====================================================================== +// Constructor & Destructor + +SecCamera::SecCamera() : + m_focus_mode(1), + m_iso(0), + m_camera_id(CAMERA_ID_BACK), + m_preview_v4lformat(-1), + m_preview_width (0), + m_preview_height (0), + m_preview_max_width (MAX_BACK_CAMERA_PREVIEW_WIDTH), + m_preview_max_height (MAX_BACK_CAMERA_PREVIEW_HEIGHT), + m_snapshot_v4lformat(-1), + m_snapshot_width (0), + m_snapshot_height (0), + m_snapshot_max_width (MAX_BACK_CAMERA_SNAPSHOT_WIDTH), + m_snapshot_max_height (MAX_BACK_CAMERA_SNAPSHOT_HEIGHT), + m_angle(0), + m_fps(30), + m_autofocus(AUTO_FOCUS_ON), + m_white_balance(WHITE_BALANCE_AUTO), + m_brightness(BRIGHTNESS_NORMAL), + m_image_effect(IMAGE_EFFECT_NONE), + #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + m_anti_banding(0), + m_flash_mode(1), + m_metering(2), + m_contrast(2), + m_saturation(2), + m_sharpness(2), + m_wdr(0), + m_anti_shake(0), + m_zoom_level(0), + m_object_tracking(0), + m_smart_auto(0), + m_beauty_shot(0), + m_vintage_mode(1), + m_face_detect(0), + m_gps_latitude(0), + m_gps_longitude(0), + m_gps_altitude(0), + m_gps_timestamp(0), + m_vtmode(0), + m_sensor_mode(0), + m_exif_orientation(1), + m_blur_level(0), + m_chk_dataline(0), + m_video_gamma(0), + m_slow_ae(0), + #else + m_image_effect(IMAGE_EFFECT_ORIGINAL), + #endif + m_flag_camera_start(0), + m_jpeg_thumbnail_width (0), + m_jpeg_thumbnail_height(0), + m_jpeg_quality(100), + m_camera_af_flag(-1), + m_shot_mode(0) +{ + LOGV("%s()", __FUNCTION__); +#ifdef BOARD_USES_SDTV + nsecs_t before1, after1; + +#ifdef MEASURE_DURATION_TVOUT + before1 = systemTime(SYSTEM_TIME_MONOTONIC); +#endif + //suspend + if(mtvoutcamera == 0) { + mtvoutcamera = TvOut::connect(); + } + if(mtvoutcamera != 0 ) + { + if (mtvoutcamera->isEnabled() ) + { + mtvoutcamera->DisableTvOut() ; // //TvOutSuspend("Tvout is not available! so what can i do, close camera or any other app which uses fimc"); + suspendTvInit = true; + } + } + +#ifdef MEASURE_DURATION_TVOUT + after1 = systemTime(SYSTEM_TIME_MONOTONIC); + LOGD("%s: MEASURE_DURATION_TVOUT duration=%lld", __func__, ns2us(after1-before1)); +#endif + +#endif + initCamera(); +} + +int SecCamera::flagCreate(void) const +{ + LOGV("%s() : %d", __FUNCTION__, m_flag_init); + return m_flag_init; +} + +SecCamera::~SecCamera() +{ + LOGV("%s()", __FUNCTION__); + + DeinitCamera(); +#ifdef BOARD_USES_SDTV + nsecs_t before1, after1; + +#ifdef MEASURE_DURATION_TVOUT + before1 = systemTime(SYSTEM_TIME_MONOTONIC); +#endif + + //resume + if(mtvoutcamera != 0 ) + { + if (!mtvoutcamera->isEnabled() && (mtvoutcamera->isSuspended() )) + { + mtvoutcamera->TvOutResume(TVOUT_RESUME_TIME); + } + } + suspendTvInit = false; +#ifdef MEASURE_DURATION_TVOUT + after1 = systemTime(SYSTEM_TIME_MONOTONIC); + LOGD("%s: MEASURE_DURATION_TVOUT duration=%lld", __func__, ns2us(after1-before1)); +#endif +#endif +} + +int SecCamera::initCamera() +{ + LOGV("%s()", __FUNCTION__); + int ret = 0, index = 0; + + if(!m_flag_init) + { + /* Arun C + * Reset the lense position only during camera starts; don't do + * reset between shot to shot + */ + m_camera_af_flag = -1; + +#ifdef BOARD_USES_SDTV + nsecs_t before1, after1; + +#ifdef MEASURE_DURATION_TVOUT + before1 = systemTime(SYSTEM_TIME_MONOTONIC); +#endif + + //suspend + if(mtvoutcamera == 0) { + mtvoutcamera = TvOut::connect(); + } + + + + if(mtvoutcamera != 0 ) + { + + if ( mtvoutcamera->isEnabled() ) + { + + mtvoutcamera->DisableTvOut() ; + suspendTvInit = true; + } + } + +#ifdef MEASURE_DURATION_TVOUT + after1 = systemTime(SYSTEM_TIME_MONOTONIC); + LOGD("%s: MEASURE_DURATION_TVOUT duration=%lld", __func__, ns2us(after1-before1)); +#endif + + +#endif +#ifndef JPEG_FROM_SENSOR + m_jpeg_fd = SsbSipJPEGEncodeInit(); + LOGD("(%s):JPEG device open ID = %d\n", __FUNCTION__,m_jpeg_fd); + if(m_jpeg_fd < 0) + { + m_jpeg_fd = 0; + LOGE("ERR(%s):Cannot open a jpeg device file\n", __FUNCTION__); + return -1; + } +#endif + + m_cam_fd_temp = -1; + m_cam_fd2_temp = -1; + + m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR); + if (m_cam_fd < 0) + { + LOGE("ERR(%s):Cannot open %s (error : %s)\n", __FUNCTION__, CAMERA_DEV_NAME, strerror(errno)); +#ifndef JPEG_FROM_SENSOR + SsbSipJPEGEncodeDeInit(m_jpeg_fd); +#endif + return -1; + } + + if(m_cam_fd < 3) { // for 0, 1, 2 + LOGE("ERR(%s):m_cam_fd is %d\n", __FUNCTION__, m_cam_fd); + + close(m_cam_fd); + + m_cam_fd_temp = open(CAMERA_DEV_NAME_TEMP, O_CREAT); + + LOGE("ERR(%s):m_cam_fd_temp is %d\n", __FUNCTION__, m_cam_fd_temp); + + m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR); + + if(m_cam_fd < 3) { // for 0, 1, 2 + LOGE("ERR(%s):retring to open %s is failed, %d\n", __FUNCTION__, CAMERA_DEV_NAME, m_cam_fd); + + if (m_cam_fd < 0){ + return -1; + } + else{ + close(m_cam_fd); + m_cam_fd = -1; + } + + if(m_cam_fd_temp != -1){ + close(m_cam_fd_temp); + m_cam_fd_temp = -1; + } + return -1; + } + } + + LOGE("initCamera: m_cam_fd(%d), m_jpeg_fd(%d)", m_cam_fd, m_jpeg_fd); + + ret = fimc_v4l2_querycap(m_cam_fd); + CHECK(ret); + index = fimc_v4l2_enuminput(m_cam_fd); + CHECK(index); + ret = fimc_v4l2_s_input(m_cam_fd, index); + CHECK(ret); + +#ifdef DUAL_PORT_RECORDING + m_cam_fd2 = open(CAMERA_DEV_NAME2, O_RDWR); + if (m_cam_fd2 < 0) + { + LOGE("ERR(%s):Cannot open %s (error : %s)\n", __FUNCTION__, CAMERA_DEV_NAME2, strerror(errno)); + return -1; + } + if(m_cam_fd2 < 3) { // for 0, 1, 2 + LOGE("ERR(%s):m_cam_fd2 is %d\n", __FUNCTION__, m_cam_fd2); + + close(m_cam_fd2); + + m_cam_fd2_temp = open(CAMERA_DEV_NAME2_TEMP, O_CREAT); + + LOGE("ERR(%s):m_cam_fd2_temp is %d\n", __FUNCTION__, m_cam_fd2_temp); + + m_cam_fd2 = open(CAMERA_DEV_NAME2, O_RDWR); + + if(m_cam_fd2 < 3) { // for 0, 1, 2 + LOGE("ERR(%s):retring to open %s is failed, %d\n", __FUNCTION__, CAMERA_DEV_NAME2, m_cam_fd2); + + if (m_cam_fd2 < 0){ + return -1; + } + else{ + close(m_cam_fd2); + m_cam_fd2 = -1; + } + + if(m_cam_fd2_temp != -1){ + close(m_cam_fd2_temp); + m_cam_fd2_temp = -1; + } + + return -1; + } + } + + if(m_cam_fd_temp != -1){ + close(m_cam_fd_temp); + m_cam_fd_temp = -1; + } + + if(m_cam_fd2_temp != -1){ + close(m_cam_fd2_temp); + m_cam_fd2_temp = -1; + } + + LOGE("initCamera: m_cam_fd2(%d)", m_cam_fd2); + + ret = fimc_v4l2_querycap(m_cam_fd2); + CHECK(ret); + index = fimc_v4l2_enuminput(m_cam_fd2); + CHECK(index); + ret = fimc_v4l2_s_input(m_cam_fd2, index); + CHECK(ret); +#endif + setExifFixedAttribute(); + + m_flag_init = 1; + } + return 0; +} + +void SecCamera::resetCamera() +{ + LOGV("%s()", __FUNCTION__); + DeinitCamera(); + initCamera(); +} + +void SecCamera::DeinitCamera() +{ + LOGV("%s()", __FUNCTION__); + + if(m_flag_init) + { +#ifndef JPEG_FROM_SENSOR + if(m_jpeg_fd > 0) + { + if(SsbSipJPEGEncodeDeInit(m_jpeg_fd) != JPEG_OK) + { + LOGE("ERR(%s):Fail on SsbSipJPEGEncodeDeInit\n", __FUNCTION__); + } + m_jpeg_fd = 0; + } +#endif + LOGE("DeinitCamera: m_cam_fd(%d)", m_cam_fd); + if(m_cam_fd > -1) + { + close(m_cam_fd); + m_cam_fd = -1; + } +#ifdef DUAL_PORT_RECORDING + LOGE("DeinitCamera: m_cam_fd2(%d)", m_cam_fd2); + if(m_cam_fd2 > -1) + { + close(m_cam_fd2); + m_cam_fd2 = -1; + } +#endif + if(m_cam_fd_temp != -1){ + close(m_cam_fd_temp); + m_cam_fd_temp = -1; + } + + if(m_cam_fd2_temp != -1){ + close(m_cam_fd2_temp); + m_cam_fd2_temp = -1; + } + +#ifdef BOARD_USES_SDTV + nsecs_t before1, after1; + +#ifdef MEASURE_DURATION_TVOUT + before1 = systemTime(SYSTEM_TIME_MONOTONIC); +#endif + + if(mtvoutcamera == 0) { + mtvoutcamera = TvOut::connect(); + + } + + //resume + if(mtvoutcamera != 0 ) + { + + if(mtvoutcamera->isSuspended()) + { + mtvoutcamera->TvOutResume(TVOUT_RESUME_TIME); + } + } +#ifdef MEASURE_DURATION_TVOUT + after1 = systemTime(SYSTEM_TIME_MONOTONIC); + LOGD("%s: MEASURE_DURATION_TVOUT duration=%lld", __func__, ns2us(after1-before1)); +#endif +#endif + m_flag_init = 0; + usleep(100000); //100 ms delay to allow proper closure of fimc device. + } +} + + +int SecCamera::getCameraFd(void) +{ + return m_cam_fd; +} + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +int SecCamera::setCameraSensorReset(void) +{ + int ret = 0; + + LOGV("%s", __FUNCTION__); + + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_RESET, 0); + CHECK(ret); + + return ret; +} + +int SecCamera::setDefultIMEI(int imei) +{ + LOGV("%s(m_default_imei (%d))", __FUNCTION__, imei); + + if(m_default_imei != imei) + { + m_default_imei = imei; + } + return 0; +} + +int SecCamera::getDefultIMEI(void) +{ + return m_default_imei; +} + + +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + + +// ====================================================================== +// Preview + +int SecCamera::flagPreviewStart(void) +{ + LOGV("%s:started(%d)", __func__, m_flag_camera_start); + + return m_flag_camera_start > 0; +} + +int SecCamera::startPreview(void) +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGV("%s()", __FUNCTION__); +#else /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + LOGE("%s()", __FUNCTION__); +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + + // aleady started + if(m_flag_camera_start > 0) + { + LOGE("ERR(%s):Preview was already started\n", __FUNCTION__); + return 0; + } + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_cam_fd; + m_events_c.events = POLLIN | POLLERR; + + /* enum_fmt, s_fmt sample */ + int ret = fimc_v4l2_enum_fmt(m_cam_fd,m_preview_v4lformat); + CHECK(ret); + ret = fimc_v4l2_s_fmt(m_cam_fd, m_preview_width,m_preview_height,m_preview_v4lformat, 0); + CHECK(ret); + + init_yuv_buffers(m_buffers_c, m_preview_width, m_preview_height, m_preview_v4lformat); + ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, MAX_BUFFERS); + CHECK(ret); + ret = fimc_v4l2_querybuf(m_cam_fd, m_buffers_c, V4L2_BUF_TYPE_VIDEO_CAPTURE, MAX_BUFFERS); + CHECK(ret); + + /* g_parm, s_parm sample */ + ret = fimc_v4l2_g_parm(m_cam_fd); + CHECK(ret); + ret = fimc_v4l2_s_parm(m_cam_fd, 1, m_fps); + CHECK(ret); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGE("%s()m_preview_width: %d m_preview_height: %d m_angle: %d\n", __FUNCTION__, m_preview_width,m_preview_height,m_angle); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_ROTATION, m_angle); + CHECK(ret); + + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CHECK_DATALINE, m_chk_dataline); + CHECK(ret); + + if(m_camera_id == CAMERA_ID_BACK) + { + /*Should be set before starting preview*/ + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_BANDING, m_anti_banding); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ISO, m_iso); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BRIGHTNESS, m_brightness); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FRAME_RATE, m_fps); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_METERING, m_metering); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_GAMMA, m_video_gamma); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_SLOW_AE, m_slow_ae); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EFFECT, m_image_effect); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WHITE_BALANCE, m_white_balance); + CHECK(ret); + } + else + { + /* VT mode setting */ + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_VT_MODE, m_vtmode); + CHECK(ret); + } + +#endif + /* start with all buffers in queue */ + for (int i = 0; i < MAX_BUFFERS; i++) + { + ret = fimc_v4l2_qbuf(m_cam_fd, i); + CHECK(ret); + } + + ret = fimc_v4l2_streamon(m_cam_fd); + CHECK(ret); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + m_flag_camera_start = 1; //Kamat check + + if(m_camera_id == CAMERA_ID_BACK) { + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EFFECT, m_image_effect); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WHITE_BALANCE, m_white_balance); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ISO, m_iso); + CHECK(ret); + if(m_focus_mode ==FOCUS_MODE_FACEDETECT) + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_AUTO); + else{ + if(m_shot_mode == 2){ //Panorama shot + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, m_focus_mode); + CHECK(ret); + m_camera_af_flag = -1; + } + else if(m_shot_mode == 3){ //Smile shot + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, m_focus_mode); + CHECK(ret); + m_camera_af_flag = -1; + } + else if (m_camera_af_flag < 0) { //After captur, Focus is fixed. + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, m_focus_mode); + CHECK(ret); + m_camera_af_flag = 0; + } + } + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FRAME_RATE, m_fps); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_METERING, m_metering); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SATURATION, m_saturation); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CONTRAST, m_contrast); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ZOOM, m_zoom_level); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SENSOR_MODE, m_sensor_mode); + CHECK(ret); + // Apply the scene mode only in camera not in camcorder + if (!m_sensor_mode) + { + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SCENE_MODE, m_scene_mode); + CHECK(ret); + } + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BRIGHTNESS, m_brightness); + CHECK(ret); + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SHARPNESS, m_sharpness); + CHECK(ret); + } + else // In case VGA camera + { + /* Brightness setting */ + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BRIGHTNESS, m_brightness); + CHECK(ret); + } +#endif + + // It is a delay for a new frame, not to show the previous bigger ugly picture frame. + ret = fimc_poll(&m_events_c); + CHECK(ret); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGE("%s: get the first frame of the preview\n", __FUNCTION__); +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + +#ifndef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + m_flag_camera_start = 1; //Kamat check +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + +#ifdef ENABLE_HDMI_DISPLAY + hdmi_initialize(m_preview_width,m_preview_height); + hdmi_gl_initialize(0); + hdmi_gl_streamoff(0); +#endif +#ifdef BOARD_USES_SDTV + + if(suspendTvInit ==true ) + { + if(!mtvoutcamera->isSuspended()) + { + mtvoutcamera->TvOutSuspend("") ; + } + } + +#endif + + return 0; +} + +int SecCamera::stopPreview(void) +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGE("%s()", __FUNCTION__); + + close_buffers(m_buffers_c); + + if(m_flag_camera_start == 0) { + LOGE("%s: m_flag_camera_start is zero", __FUNCTION__); + return 0; + } +#else /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + LOGV("%s()", __FUNCTION__); + + close_buffers(m_buffers_c); + + if(m_flag_camera_start == 0) + return 0; +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ +#ifdef ENABLE_HDMI_DISPLAY + hdmi_deinitialize(); + hdmi_gl_streamon(0); +#endif + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + int ret = fimc_v4l2_streamoff(m_cam_fd); + + m_flag_camera_start = 0; //Kamat check + CHECK(ret); + + return ret; +} + +//Recording +#ifdef DUAL_PORT_RECORDING +int SecCamera::startRecord(void) +{ + LOGV("%s()", __FUNCTION__); + + // aleady started + if(m_flag_record_start > 0) + { + LOGE("ERR(%s):Preview was already started\n", __FUNCTION__); + return 0; + } + + if(m_cam_fd2 <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + memset(&m_events_c2, 0, sizeof(m_events_c2)); + m_events_c2.fd = m_cam_fd2; + m_events_c2.events = POLLIN | POLLERR; + + int m_record_v4lformat = V4L2_PIX_FMT_NV12T; //Kamat: set suitably + /* enum_fmt, s_fmt sample */ + int ret = fimc_v4l2_enum_fmt(m_cam_fd2,m_record_v4lformat); + CHECK(ret); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGE("%s: m_recording_width = %d, m_recording_height = %d\n", __FUNCTION__, m_recording_width, m_recording_height); + + ret = fimc_v4l2_s_fmt(m_cam_fd2, m_recording_width, m_recording_height,m_record_v4lformat, 0); + + CHECK(ret); + + init_yuv_buffers(m_buffers_c2, m_recording_width, m_recording_height, m_record_v4lformat); +#else /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + ret = fimc_v4l2_s_fmt(m_cam_fd2, m_preview_width,m_preview_height,m_record_v4lformat, 0); + CHECK(ret); + + init_yuv_buffers(m_buffers_c2, m_preview_width, m_preview_height, m_record_v4lformat); +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + + ret = fimc_v4l2_reqbufs(m_cam_fd2, V4L2_BUF_TYPE_VIDEO_CAPTURE, MAX_BUFFERS); + CHECK(ret); + ret = fimc_v4l2_querybuf(m_cam_fd2, m_buffers_c2, V4L2_BUF_TYPE_VIDEO_CAPTURE, MAX_BUFFERS); + CHECK(ret); + + /* g_parm, s_parm sample */ + ret = fimc_v4l2_g_parm(m_cam_fd2); + CHECK(ret); + ret = fimc_v4l2_s_parm(m_cam_fd2, 1, m_fps); + CHECK(ret); + + /* start with all buffers in queue */ + for (int i = 0; i < MAX_BUFFERS; i++) + { + ret = fimc_v4l2_qbuf(m_cam_fd2, i); + CHECK(ret); + } + + ret = fimc_v4l2_streamon(m_cam_fd2); + CHECK(ret); + + // It is a delay for a new frame, not to show the previous bigger ugly picture frame. + ret = fimc_poll(&m_events_c2); + CHECK(ret); + + m_flag_record_start = 1; //Kamat check + + return 0; +} + +int SecCamera::stopRecord(void) +{ + if(m_flag_record_start == 0) + return 0; + + LOGV("%s()", __FUNCTION__); + + close_buffers(m_buffers_c2); + + if(m_cam_fd2 <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + int ret = fimc_v4l2_streamoff(m_cam_fd2); + + m_flag_record_start = 0; //Kamat check + CHECK(ret); + + return 0; +} + +unsigned int SecCamera::getRecPhyAddrY(int index) +{ + unsigned int addr_y; + + addr_y = fimc_v4l2_s_ctrl(m_cam_fd2, V4L2_CID_PADDR_Y, index); + CHECK((int)addr_y); + return addr_y; +} + +unsigned int SecCamera::getRecPhyAddrC(int index) +{ + unsigned int addr_c; + + addr_c = fimc_v4l2_s_ctrl(m_cam_fd2, V4L2_CID_PADDR_CBCR, index); + CHECK((int)addr_c); + return addr_c; +} +#endif //DUAL_PORT_RECORDING + +unsigned int SecCamera::getPhyAddrY(int index) +{ + unsigned int addr_y; + + addr_y = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_PADDR_Y, index); + CHECK((int)addr_y); + return addr_y; +} + +unsigned int SecCamera::getPhyAddrC(int index) +{ + unsigned int addr_c; + + addr_c = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_PADDR_CBCR, index); + CHECK((int)addr_c); + return addr_c; +} + +#ifdef SEND_YUV_RECORD_DATA +#define PAGE_ALIGN(x) ((x+0xFFF)&(~0xFFF)) // Set as multiple of 4K +void SecCamera::getYUVBuffers(unsigned char** virYAddr, unsigned char** virCAddr, int index) +{ + *virYAddr = (unsigned char*)m_buffers_c[index].start; + //*virCAddr = (unsigned char*)m_buffers_c[index].start + PAGE_ALIGN(m_preview_width * m_preview_height); + *virCAddr = (unsigned char*)m_buffers_c[index].start + ALIGN_TO_8KB(ALIGN_TO_128B(m_preview_width) * ALIGN_TO_32B(m_preview_height)); +} +#endif + +void SecCamera::pausePreview() +{ + fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_STREAM_PAUSE, 0); +} + +int SecCamera::getPreview() +{ + int index; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + int ret; +#endif + +#ifdef PERFORMANCE + + LOG_TIME_DEFINE(0) + LOG_TIME_DEFINE(1) + + LOG_TIME_START(0) + fimc_poll(&m_events_c); + LOG_TIME_END(0) + LOG_CAMERA("fimc_poll interval: %lu us", LOG_TIME(0)); + + LOG_TIME_START(1) + index = fimc_v4l2_dqbuf(m_cam_fd); + LOG_TIME_END(1) + LOG_CAMERA("fimc_dqbuf interval: %lu us", LOG_TIME(1)); + +#else +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_flag_camera_start == 0 || fimc_esd_poll(&m_events_c) == 0) + { + LOGE("ERR(%s):Start Camera Device Reset \n", __FUNCTION__); + /* GAUDI Project([arun.c@samsung.com]) 2010.05.20. [Implemented ESD code] */ + /* + * When there is no data for more than 1 second from the camera we inform + * the FIMC driver by calling fimc_v4l2_s_input() with a special value = 1000 + * FIMC driver identify that there is something wrong with the camera + * and it restarts the sensor. + */ + stopPreview(); + /* Reset Only Camera Device */ + ret = fimc_v4l2_querycap(m_cam_fd); + CHECK(ret); + index = fimc_v4l2_enuminput(m_cam_fd); + CHECK(index); + ret = fimc_v4l2_s_input(m_cam_fd, 1000); + CHECK(ret); + //setCameraSensorReset(); + ret = startPreview(); + + if(ret < 0) { + LOGE("ERR(%s): startPreview() return %d\n", __FUNCTION__, ret); + + return 0; + } + } +#else /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + fimc_poll(&m_events_c); +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + index = fimc_v4l2_dqbuf(m_cam_fd); +#endif + if(!(0 <= index && index < MAX_BUFFERS)) + { + LOGE("ERR(%s):wrong index = %d\n", __FUNCTION__, index); + return -1; + } + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + ret = fimc_v4l2_qbuf(m_cam_fd, index); //Kamat: is it overhead? +#else /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + int ret = fimc_v4l2_qbuf(m_cam_fd, index); //Kamat: is it overhead? +#endif /* SWP1_CAMERA_ADD_ADVANCED_FUNCTION */ + + CHECK(ret); + +#ifdef ENABLE_HDMI_DISPLAY + hdmi_set_v_param(getPhyAddrY(index), getPhyAddrC (index),m_preview_width,m_preview_height); +#endif + return index; + +} + +#ifdef DUAL_PORT_RECORDING +int SecCamera::getRecord() +{ + int index; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_flag_record_start == 0) { + LOGE("%s: m_flag_record_start is 0", __FUNCTION__); + startRecord(); + } +#endif + +#ifdef PERFORMANCE + + LOG_TIME_DEFINE(0) + LOG_TIME_DEFINE(1) + + LOG_TIME_START(0) + fimc_poll(&m_events_c2); + LOG_TIME_END(0) + LOG_CAMERA("fimc_poll interval: %lu us", LOG_TIME(0)); + + LOG_TIME_START(1) + index = fimc_v4l2_dqbuf(m_cam_fd2); + LOG_TIME_END(1) + LOG_CAMERA("fimc_dqbuf interval: %lu us", LOG_TIME(1)); + +#else + fimc_poll(&m_events_c2); + index = fimc_v4l2_dqbuf(m_cam_fd2); +#endif + if(!(0 <= index && index < MAX_BUFFERS)) + { + LOGE("ERR(%s):wrong index = %d\n", __FUNCTION__, index); + return -1; + } + + int ret = fimc_v4l2_qbuf(m_cam_fd2, index); //Kamat: is it overhead? + CHECK(ret); + + return index; +} +#endif //DUAL_PORT_RECORDING + +int SecCamera::setPreviewSize(int width, int height, int pixel_format) +{ + LOGV("%s(width(%d), height(%d), format(%d))", __FUNCTION__, width, height, pixel_format); + + int v4lpixelformat = pixel_format; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if(v4lpixelformat == V4L2_PIX_FMT_YUV420) { LOGV("PreviewFormat:V4L2_PIX_FMT_YUV420"); } + else if(v4lpixelformat == V4L2_PIX_FMT_NV12) { LOGV("PreviewFormat:V4L2_PIX_FMT_NV12"); } + else if(v4lpixelformat == V4L2_PIX_FMT_NV12T) { LOGV("PreviewFormat:V4L2_PIX_FMT_NV12T"); } + else if(v4lpixelformat == V4L2_PIX_FMT_NV21) { LOGV("PreviewFormat:V4L2_PIX_FMT_NV21"); } + else if(v4lpixelformat == V4L2_PIX_FMT_YUV422P) { LOGV("PreviewFormat:V4L2_PIX_FMT_YUV422P"); } + else if(v4lpixelformat == V4L2_PIX_FMT_YUYV) { LOGV("PreviewFormat:V4L2_PIX_FMT_YUYV"); } + else if(v4lpixelformat == V4L2_PIX_FMT_RGB565) { LOGV("PreviewFormat:V4L2_PIX_FMT_RGB565"); } + else { LOGV("PreviewFormat:UnknownFormat"); } +#endif + m_preview_width = width; + m_preview_height = height; + m_preview_v4lformat = v4lpixelformat; + + return 0; +} + +int SecCamera::getPreviewSize(int * width, int * height, int * frame_size) +{ + *width = m_preview_width; + *height = m_preview_height; + *frame_size = m_frameSize(m_preview_v4lformat, m_preview_width, m_preview_height); + + return 0; +} + +int SecCamera::getPreviewMaxSize(int * width, int * height) +{ + *width = m_preview_max_width; + *height = m_preview_max_height; + + return 0; +} + +int SecCamera::getPreviewPixelFormat(void) +{ + return m_preview_v4lformat; +} + + +// ====================================================================== +// Snapshot +#ifdef JPEG_FROM_SENSOR +/* + * Devide getJpeg() as two funcs, setSnapshotCmd() & getJpeg() because of the shutter sound timing. + * Here, just send the capture cmd to camera ISP to start JPEG capture. + */ +int SecCamera::setSnapshotCmd(void) +{ + LOGV("%s()", __FUNCTION__); + + int ret = 0; + + LOG_TIME_DEFINE(0) + LOG_TIME_DEFINE(1) + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return 0; + } + + if(m_flag_camera_start > 0) + { + LOG_TIME_START(0) + stopPreview(); + LOG_TIME_END(0) + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_cam_fd; + m_events_c.events = POLLIN | POLLERR; + + LOG_TIME_START(1) // prepare + int nframe = 1; + + ret = fimc_v4l2_enum_fmt(m_cam_fd,m_snapshot_v4lformat); + CHECK_PTR(ret); + ret = fimc_v4l2_s_fmt_cap(m_cam_fd, m_snapshot_width, m_snapshot_height, V4L2_PIX_FMT_JPEG); + CHECK_PTR(ret); + init_yuv_buffers(m_buffers_c, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + + ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); + CHECK_PTR(ret); + ret = fimc_v4l2_querybuf(m_cam_fd, m_buffers_c, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); + CHECK_PTR(ret); + + ret = fimc_v4l2_g_parm(m_cam_fd); + CHECK_PTR(ret); + ret = fimc_v4l2_s_parm(m_cam_fd, 1, m_fps); + CHECK_PTR(ret); + + ret = fimc_v4l2_qbuf(m_cam_fd, 0); + CHECK_PTR(ret); + + ret = fimc_v4l2_streamon(m_cam_fd); + CHECK_PTR(ret); + LOG_TIME_END(1) + + return 0; +} + +/* + * Set Jpeg quality & exif info and get JPEG data from camera ISP + */ +unsigned char* SecCamera::getJpeg(int* jpeg_size, unsigned int* phyaddr) +{ + LOGV("%s()", __FUNCTION__); + + int index, ret = 0; + unsigned char* addr; + + LOG_TIME_DEFINE(2) +/* kidggang (10.7.5) - Problem - After jpegquality is capture, operation setting is normal. + + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_QUALITY, m_jpeg_quality); + CHECK_PTR(ret); +*/ + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + //exif orient info +// ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EXIF_ORIENTATION, m_exif_orientation); //kidggang +// CHECK_PTR(ret); +#if 0//def SWP1_CAMERA_ADD_ADVANCED_FUNCTION + //set gps information + ret = fimc_v4l2_s_ext_ctrl(m_cam_fd, V4L2_CID_CAMERA_GPS_LATITUDE, &m_gps_latitude); + CHECK_PTR(ret); + ret = fimc_v4l2_s_ext_ctrl(m_cam_fd, V4L2_CID_CAMERA_GPS_LONGITUDE, &m_gps_longitude); + CHECK_PTR(ret); + ret = fimc_v4l2_s_ext_ctrl(m_cam_fd, V4L2_CID_CAMERA_GPS_ALTITUDE, &m_gps_altitude); + CHECK_PTR(ret); + ret = fimc_v4l2_s_ext_ctrl(m_cam_fd, V4L2_CID_CAMERA_GPS_TIMESTAMP, &m_gps_timestamp); + CHECK_PTR(ret); +#endif + +/* kidggang + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CAPTURE, 0); + CHECK_PTR(ret);*/ + + // capture + ret = fimc_poll(&m_events_c); + CHECK_PTR(ret); + index = fimc_v4l2_dqbuf(m_cam_fd); + if(!(0 <= index && index < MAX_BUFFERS)) + { + LOGE("ERR(%s):wrong index = %d\n", __FUNCTION__, index); + return NULL; + } +#endif + + *jpeg_size = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_MAIN_SIZE); + CHECK_PTR(*jpeg_size); + int main_offset = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_MAIN_OFFSET); + CHECK_PTR(main_offset); + m_postview_offset = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET); + CHECK_PTR(m_postview_offset); + + ret = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_STREAM_PAUSE, 0); + CHECK_PTR(ret); + LOGV("\nsnapshot dqueued buffer = %d snapshot_width = %d snapshot_height = %d\n\n",index, m_snapshot_width, m_snapshot_height); + + addr = (unsigned char*)(m_buffers_c[index].start) + main_offset; + *phyaddr = getPhyAddrY(index) + m_postview_offset; + + LOG_TIME_START(2) // post + ret = fimc_v4l2_streamoff(m_cam_fd); + CHECK_PTR(ret); + LOG_TIME_END(2) + +#if 0 //temporary blocked for build + LOG_CAMERA("getSnapshotAndJpeg intervals : stopPreview(%lu), prepare(%lu), capture(%lu), memcpy(%lu), yuv2Jpeg(%lu), post(%lu) us" + , LOG_TIME(0), LOG_TIME(1), LOG_TIME(2), LOG_TIME(3), LOG_TIME(4), LOG_TIME(5)); +#endif + return addr; +} + +int SecCamera::getExif(unsigned char *pExifDst, unsigned char *pThumbSrc) +{ + JpegEncoder jpgEnc; +#if ADD_THUMB_IMG + int inFormat = JPG_MODESEL_YCBCR; + int outFormat = JPG_422; + switch(m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + outFormat = JPG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + outFormat = JPG_422; + break; + } + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_IN_FORMAT, inFormat) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_SAMPING_MODE, outFormat) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_QUALITY, JPG_QUALITY_LEVEL_2) != JPG_SUCCESS) + return -1; + + int thumbWidth, thumbHeight, thumbSrcSize; + getPostViewConfig(&thumbWidth, &thumbHeight, &thumbSrcSize); + if (jpgEnc.setConfig(JPEG_SET_ENCODE_WIDTH, thumbWidth) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_HEIGHT, thumbHeight) != JPG_SUCCESS) + return -1; + + char *pInBuf = (char *)jpgEnc.getInBuf(thumbSrcSize); + if(pInBuf == NULL) + return -1; + memcpy(pInBuf, pThumbSrc, thumbSrcSize); + unsigned int thumbSize; + jpgEnc.encode(&thumbSize, NULL); + + mExifInfo.enableThumb = true; +#else + mExifInfo.enableThumb = false; +#endif + + unsigned int exifSize; + setExifChangedAttribute(); + jpgEnc.makeExif(pExifDst, &mExifInfo, &exifSize, true); + + return exifSize; +} + +void SecCamera::getPostViewConfig(int* width, int* height, int* size) +{ + if(m_preview_width == 1024) + { + *width = BACK_CAMERA_POSTVIEW_WIDE_WIDTH; + *height = BACK_CAMERA_POSTVIEW_HEIGHT; + *size = BACK_CAMERA_POSTVIEW_WIDE_WIDTH * BACK_CAMERA_POSTVIEW_HEIGHT * BACK_CAMERA_POSTVIEW_BPP/8; + + } + else + { + *width = BACK_CAMERA_POSTVIEW_WIDTH; + *height = BACK_CAMERA_POSTVIEW_HEIGHT; + *size = BACK_CAMERA_POSTVIEW_WIDTH * BACK_CAMERA_POSTVIEW_HEIGHT * BACK_CAMERA_POSTVIEW_BPP/8; + } + LOGV("[5B] m_preview_width : %d, mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d", m_preview_width, *width, *height, *size); +} + +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA +int SecCamera::getPostViewOffset(void) +{ + return m_postview_offset; +} +#endif + +#else //#ifdef JPEG_FROM_SENSOR +int SecCamera::getJpegFd(void) +{ + return m_jpeg_fd; +} + +void SecCamera::SetJpgAddr(unsigned char *addr) +{ + SetMapAddr(addr); +} + +#if 0 +int SecCamera::getSnapshot(unsigned char * buffer, unsigned int buffer_size) +{ + LOGV("%s(buffer(%p), size(%d))", __FUNCTION__, buffer, buffer_size); + + if(getSnapshotAndJpeg(buffer, buffer_size, NULL, NULL) == 0) + return -1; + + return 0; +} +#endif + +#endif + +unsigned char* SecCamera::getSnapshotAndJpeg() +{ + LOGV("%s()", __FUNCTION__); + + int index; + //unsigned int addr; + unsigned char* addr; + int ret = 0; + + LOG_TIME_DEFINE(0) + LOG_TIME_DEFINE(1) + LOG_TIME_DEFINE(2) + LOG_TIME_DEFINE(3) + LOG_TIME_DEFINE(4) + LOG_TIME_DEFINE(5) + + //fimc_v4l2_streamoff(m_cam_fd); [zzangdol] remove - it is separate in HWInterface with camera_id + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return 0; + } + + if(m_flag_camera_start > 0) + { + LOG_TIME_START(0) + stopPreview(); + LOG_TIME_END(0) + } + + memset(&m_events_c, 0, sizeof(m_events_c)); + m_events_c.fd = m_cam_fd; + m_events_c.events = POLLIN | POLLERR; + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) { LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV420"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) { LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) { LOGV("SnapshotFormat:V4L2_PIX_FMT_NV12T"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) { LOGV("SnapshotFormat:V4L2_PIX_FMT_NV21"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) { LOGV("SnapshotFormat:V4L2_PIX_FMT_YUV422P"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) { LOGV("SnapshotFormat:V4L2_PIX_FMT_YUYV"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) { LOGV("SnapshotFormat:V4L2_PIX_FMT_UYVY"); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { LOGV("SnapshotFormat:V4L2_PIX_FMT_RGB565"); } + else { LOGV("SnapshotFormat:UnknownFormat"); } +#endif + + LOG_TIME_START(1) // prepare + int nframe = 1; + + LOGE("[zzangdol] w %d, h %d\n", m_snapshot_width, m_snapshot_height); + + ret = fimc_v4l2_enum_fmt(m_cam_fd,m_snapshot_v4lformat); + CHECK_PTR(ret); + ret = fimc_v4l2_s_fmt_cap(m_cam_fd, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + CHECK_PTR(ret); + init_yuv_buffers(m_buffers_c, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + + ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); + CHECK_PTR(ret); + ret = fimc_v4l2_querybuf(m_cam_fd, m_buffers_c, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); + CHECK_PTR(ret); + + /* g_parm, s_parm sample */ + ret = fimc_v4l2_g_parm(m_cam_fd); + CHECK_PTR(ret); + ret = fimc_v4l2_s_parm(m_cam_fd, 1, m_fps); + CHECK_PTR(ret); + + ret = fimc_v4l2_qbuf(m_cam_fd, 0); + CHECK_PTR(ret); + + ret = fimc_v4l2_streamon(m_cam_fd);//zzangdolp + CHECK_PTR(ret); + LOG_TIME_END(1) + + LOG_TIME_START(2) // capture + fimc_poll(&m_events_c); + index = fimc_v4l2_dqbuf(m_cam_fd); + fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_STREAM_PAUSE, 0); + LOGV("\nsnapshot dqueued buffer = %d snapshot_width = %d snapshot_height = %d\n\n",index, m_snapshot_width, m_snapshot_height); + +#ifdef DUMP_YUV + save_yuv(m_buffers_c, m_snapshot_width, m_snapshot_height, 16, index, 0); +#endif + LOG_TIME_END(2) + + //addr = getPhyAddrY(index); + addr = (unsigned char*)m_buffers_c[index].start; + if(addr == 0) + { + LOGE("%s] Physical address 0"); + } + LOG_TIME_START(5) // post + fimc_v4l2_streamoff(m_cam_fd); +#ifdef DUMP_YUV + close_buffers(m_buffers_c); +#endif + LOG_TIME_END(5) + + LOG_CAMERA("getSnapshotAndJpeg intervals : stopPreview(%lu), prepare(%lu), capture(%lu), memcpy(%lu), yuv2Jpeg(%lu), post(%lu) us" + , LOG_TIME(0), LOG_TIME(1), LOG_TIME(2), LOG_TIME(3), LOG_TIME(4), LOG_TIME(5)); + + return addr; +} + + +int SecCamera::setSnapshotSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __FUNCTION__, width, height); + + m_snapshot_width = width; + m_snapshot_height = height; + + return 0; +} + +int SecCamera::getSnapshotSize(int * width, int * height, int * frame_size) +{ + *width = m_snapshot_width; + *height = m_snapshot_height; + + int frame = 0; + + frame = m_frameSize(m_snapshot_v4lformat, m_snapshot_width, m_snapshot_height); + + // set it big. + if(frame == 0) + frame = m_snapshot_width * m_snapshot_height * BPP; + + *frame_size = frame; + + return 0; +} + +int SecCamera::getSnapshotMaxSize(int * width, int * height) +{ + switch(m_camera_id) + { + case CAMERA_ID_FRONT: + m_snapshot_max_width = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT; + break; + + default: + case CAMERA_ID_BACK: + m_snapshot_max_width = MAX_BACK_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT; + break; + } + + *width = m_snapshot_max_width; + *height = m_snapshot_max_height; + + return 0; +} + +int SecCamera::setSnapshotPixelFormat(int pixel_format) +{ + int v4lpixelformat= pixel_format; + + if(m_snapshot_v4lformat != v4lpixelformat) + { + m_snapshot_v4lformat = v4lpixelformat; + } + + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 + if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUV420) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_YUV420", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV12) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_NV12", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV12T) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_NV12T", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_NV21) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_NV21", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUV422P) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_YUV422P", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_YUYV) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_YUYV", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_UYVY) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_UYVY", __FUNCTION__); } + else if(m_snapshot_v4lformat == V4L2_PIX_FMT_RGB565) { LOGE("%s():SnapshotFormat:V4L2_PIX_FMT_RGB565", __FUNCTION__); } + else { LOGE("SnapshotFormat:UnknownFormat"); } +#endif + + return 0; +} + +int SecCamera::getSnapshotPixelFormat(void) +{ + return m_snapshot_v4lformat; +} + + +// ====================================================================== +// Settings + +int SecCamera::setCameraId(int camera_id) +{ + if( camera_id != CAMERA_ID_FRONT + && camera_id != CAMERA_ID_BACK) + { + LOGE("ERR(%s)::Invalid camera id(%d)\n", __func__, camera_id); + return -1; + } + if(m_camera_id == camera_id) + return 0; + + LOGV("%s(camera_id(%d))", __FUNCTION__, camera_id); + + switch(camera_id) + { + case CAMERA_ID_FRONT: + + m_preview_max_width = MAX_FRONT_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_FRONT_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_FRONT_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT; + cam_id = 1; + break; + + case CAMERA_ID_BACK: + m_preview_max_width = MAX_BACK_CAMERA_PREVIEW_WIDTH; + m_preview_max_height = MAX_BACK_CAMERA_PREVIEW_HEIGHT; + m_snapshot_max_width = MAX_BACK_CAMERA_SNAPSHOT_WIDTH; + m_snapshot_max_height = MAX_BACK_CAMERA_SNAPSHOT_HEIGHT; + cam_id = 0; + break; + } + + m_camera_id = camera_id; + + resetCamera(); + + return 0; +} + +int SecCamera::getCameraId(void) +{ + return m_camera_id; +} + +// ----------------------------------- + +int SecCamera::setAutofocus(void) +{ + LOGV("%s()", __FUNCTION__); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_ON) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __FUNCTION__); + return -1; + } +#else + // kcoolsw : turn on setAutofocus initially.. + if(m_autofocus != AUTO_FOCUS_ON) + { + m_autofocus = AUTO_FOCUS_ON; + } +#endif + + return 0; +} + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +int SecCamera::getAutoFocusResult(void) +{ + int af_result = 0; + af_result = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT); + return af_result; +} +int SecCamera::cancelAutofocus(void) +{ + LOGV("%s()", __FUNCTION__); + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __FUNCTION__); + return -1; + } + + usleep(1000); + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_STATUS) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_AUTO_FOCUS", __FUNCTION__); + return -1; + } + return 0; +} +#endif +// ----------------------------------- + +int SecCamera::zoomIn(void) +{ + LOGV("%s()", __FUNCTION__); + return 0; +} + +int SecCamera::zoomOut(void) +{ + LOGV("%s()", __FUNCTION__); + return 0; +} + +// ----------------------------------- + +int SecCamera::SetRotate(int angle) +{ + LOGE("%s(angle(%d))", __FUNCTION__, angle); +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_angle != angle) + { + switch(angle) + { + case -360 : + case 0 : + case 360 : + m_angle = 0; + break; + + case -270 : + case 90 : + m_angle = 90; + break; + + case -180 : + case 180 : + m_angle = 180; + break; + + case -90 : + case 270 : + m_angle = 270; + break; + + default : + LOGE("ERR(%s):Invalid angle(%d)", __FUNCTION__, angle); + return -1; + } + + + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_ROTATION, angle) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_ROTATION", __FUNCTION__); + return -1; + } + } + } +#endif + return 0; +} + +int SecCamera::getRotate(void) +{ + LOGV("%s():angle(%d)", __FUNCTION__, m_angle); + return m_angle; +} + +void SecCamera::setFrameRate(int frame_rate) +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGV("%s(FrameRate(%d))", __FUNCTION__, frame_rate); + + if(frame_rate < FRAME_RATE_AUTO || FRAME_RATE_MAX < frame_rate ) + LOGE("ERR(%s):Invalid frame_rate(%d)", __FUNCTION__, frame_rate); + + if(m_fps != frame_rate) + { + m_fps = frame_rate; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FRAME_RATE, frame_rate) < 0) + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FRAME_RATE", __FUNCTION__); + } + } +#else + m_fps = frame_rate; +#endif + +} + +/* kidggang (10.7.5) - Problem - After jpegquality is capture, operation setting is normal. +void SecCamera::setJpegQuality(int quality) +{ + m_jpeg_quality = quality; +} +*/ +// ----------------------------------- + +int SecCamera::setVerticalMirror(void) +{ + LOGV("%s()", __FUNCTION__); + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_VFLIP, 0) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_VFLIP", __FUNCTION__); + return -1; + } + + return 0; +} + +int SecCamera::setHorizontalMirror(void) +{ + LOGV("%s()", __FUNCTION__); + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_HFLIP, 0) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_HFLIP", __FUNCTION__); + return -1; + } + + return 0; +} + +// ----------------------------------- + +int SecCamera::setWhiteBalance(int white_balance) +{ + LOGV("%s(white_balance(%d))", __FUNCTION__, white_balance); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(white_balance <= WHITE_BALANCE_BASE || WHITE_BALANCE_MAX <= white_balance) +#else + if(white_balance < WHITE_BALANCE_AUTO || WHITE_BALANCE_SUNNY < white_balance) +#endif + { + LOGE("ERR(%s):Invalid white_balance(%d)", __FUNCTION__, white_balance); + return -1; + } + + if(m_white_balance != white_balance) + { + m_white_balance = white_balance; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WHITE_BALANCE, white_balance) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WHITE_BALANCE", __FUNCTION__); + return -1; + } + } +#endif + } + + return 0; +} + +int SecCamera::getWhiteBalance(void) +{ + LOGV("%s():white_balance(%d)", __FUNCTION__, m_white_balance); + return m_white_balance; +} + +// ----------------------------------- + +int SecCamera::setBrightness(int brightness) +{ + LOGV("%s(brightness(%d))", __FUNCTION__, brightness); + + if(brightness < BRIGHTNESS_MINUS_4|| BRIGHTNESS_PLUS_4< brightness ) + { + LOGE("ERR(%s):Invalid brightness(%d)", __FUNCTION__, brightness); + return -1; + } + + if(m_brightness != brightness) + { + m_brightness = brightness; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BRIGHTNESS, brightness) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BRIGHTNESS", __FUNCTION__); + return -1; + } + } +#endif + } + + return 0; +} + +int SecCamera::getBrightness(void) +{ + LOGV("%s():brightness(%d)", __FUNCTION__, m_brightness); + return m_brightness; +} + +// ----------------------------------- + +int SecCamera::setImageEffect(int image_effect) +{ + LOGV("%s(image_effect(%d))", __FUNCTION__, image_effect); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(image_effect <= IMAGE_EFFECT_BASE || IMAGE_EFFECT_MAX <= image_effect) +#else + if(image_effect < IMAGE_EFFECT_ORIGINAL || IMAGE_EFFECT_SILHOUETTE < image_effect) +#endif + { + LOGE("ERR(%s):Invalid image_effect(%d)", __FUNCTION__, image_effect); + return -1; + } + + if(m_image_effect != image_effect) + { + m_image_effect = image_effect; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_EFFECT, image_effect) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_EFFECT", __FUNCTION__); + return -1; + } + } +#endif + } + + return 0; +} + +int SecCamera::getImageEffect(void) +{ + LOGV("%s():image_effect(%d)", __FUNCTION__, m_image_effect); + return m_image_effect; +} + +// ====================================================================== +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +int SecCamera::setAntiBanding(int anti_banding) +{ + LOGV("%s(anti_banding(%d))", __FUNCTION__, anti_banding); + + if(anti_banding < ANTI_BANDING_AUTO|| ANTI_BANDING_OFF < anti_banding) + { + LOGE("ERR(%s):Invalid anti_banding (%d)", __FUNCTION__, anti_banding); + return -1; + } + + if(m_anti_banding != anti_banding) + { + m_anti_banding = anti_banding; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_BANDING, anti_banding) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_BANDING", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +//====================================================================== +int SecCamera::setSceneMode(int scene_mode) +{ + LOGV("%s(scene_mode(%d))", __FUNCTION__, scene_mode); + + if(scene_mode <= SCENE_MODE_BASE || SCENE_MODE_MAX <= scene_mode) + { + LOGE("ERR(%s):Invalid scene_mode (%d)", __FUNCTION__, scene_mode); + return -1; + } + + if(m_scene_mode != scene_mode) + { + m_scene_mode = scene_mode; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SCENE_MODE, m_scene_mode) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SCENE_MODE", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSceneMode(void) +{ + return m_scene_mode; +} + +//====================================================================== + +int SecCamera::setFlashMode(int flash_mode) +{ + LOGV("%s(flash_mode(%d))", __FUNCTION__, flash_mode); + + if(flash_mode <= FLASH_MODE_BASE || FLASH_MODE_MAX <= flash_mode) + { + LOGE("ERR(%s):Invalid flash_mode (%d)", __FUNCTION__, flash_mode); + return -1; + } + + if(m_flash_mode != flash_mode) + { + m_flash_mode = flash_mode; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FLASH_MODE, flash_mode) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FLASH_MODE", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getFlashMode(void) +{ + return m_flash_mode; +} + +//====================================================================== + +int SecCamera::setISO(int iso_value) +{ + LOGV("%s(iso_value(%d))", __FUNCTION__, iso_value); + if(iso_value <ISO_AUTO || ISO_MAX <= iso_value) + { + LOGE("ERR(%s):Invalid iso_value (%d)", __FUNCTION__, iso_value); + return -1; + } + + if(m_iso != iso_value) + { + m_iso = iso_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ISO, iso_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ISO", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getISO(void) +{ + return m_iso; +} + +//====================================================================== + +int SecCamera::setContrast(int contrast_value) +{ + LOGV("%s(contrast_value(%d))", __FUNCTION__, contrast_value); + + if(contrast_value <CONTRAST_MINUS_2|| CONTRAST_MAX<= contrast_value) + { + LOGE("ERR(%s):Invalid contrast_value (%d)", __FUNCTION__, contrast_value); + return -1; + } + + if(m_contrast != contrast_value) + { + m_contrast = contrast_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CONTRAST, contrast_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CONTRAST", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getContrast(void) +{ + return m_contrast; +} + +//====================================================================== + +int SecCamera::setSaturation(int saturation_value) +{ + LOGV("%s(saturation_value(%d))", __FUNCTION__, saturation_value); + + if(saturation_value <SATURATION_MINUS_2|| SATURATION_MAX<= saturation_value) + { + LOGE("ERR(%s):Invalid saturation_value (%d)", __FUNCTION__, saturation_value); + return -1; + } + + if(m_saturation!= saturation_value) + { + m_saturation = saturation_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SATURATION, saturation_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SATURATION", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSaturation(void) +{ + return m_saturation; +} + +//====================================================================== + +int SecCamera::setSharpness(int sharpness_value) +{ + LOGV("%s(sharpness_value(%d))", __FUNCTION__, sharpness_value); + + if(sharpness_value <SHARPNESS_MINUS_2|| SHARPNESS_MAX<= sharpness_value) + { + LOGE("ERR(%s):Invalid sharpness_value (%d)", __FUNCTION__, sharpness_value); + return -1; + } + + if(m_sharpness!= sharpness_value) + { + m_sharpness = sharpness_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SHARPNESS, sharpness_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SHARPNESS", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSharpness(void) +{ + return m_sharpness; +} + +//====================================================================== + +int SecCamera::setWDR(int wdr_value) +{ + LOGV("%s(wdr_value(%d))", __FUNCTION__, wdr_value); + + if(wdr_value<WDR_OFF || WDR_MAX<= wdr_value) + { + LOGE("ERR(%s):Invalid wdr_value (%d)", __FUNCTION__, wdr_value); + return -1; + } + + if(m_wdr!= wdr_value) + { + m_wdr = wdr_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_WDR, wdr_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_WDR", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getWDR(void) +{ + return m_wdr; +} + +//====================================================================== + +int SecCamera::setAntiShake(int anti_shake) +{ + LOGV("%s(anti_shake(%d))", __FUNCTION__, anti_shake); + + if(anti_shake<ANTI_SHAKE_OFF || ANTI_SHAKE_MAX<= anti_shake) + { + LOGE("ERR(%s):Invalid anti_shake (%d)", __FUNCTION__, anti_shake); + return -1; + } + + if(m_anti_shake!= anti_shake) + { + m_anti_shake = anti_shake; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ANTI_SHAKE, anti_shake) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ANTI_SHAKE", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getAntiShake(void) +{ + return m_anti_shake; +} + +//====================================================================== + + +int SecCamera::setMetering(int metering_value) +{ + LOGV("%s(metering (%d))", __FUNCTION__, metering_value); + + if(metering_value <= METERING_BASE || METERING_MAX <= metering_value) + { + LOGE("ERR(%s):Invalid metering_value (%d)", __FUNCTION__, metering_value); + return -1; + } + + if(m_metering != metering_value) + { + m_metering = metering_value; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_METERING, metering_value) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_METERING", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getMetering(void) +{ + return m_metering; +} + +//====================================================================== + +int SecCamera::setJpegQuality(int jpeg_quality) +{ + LOGV("%s(jpeg_quality (%d))", __FUNCTION__, jpeg_quality); + + if(jpeg_quality < JPEG_QUALITY_ECONOMY|| JPEG_QUALITY_MAX<= jpeg_quality) + { + LOGE("ERR(%s):Invalid jpeg_quality (%d)", __FUNCTION__, jpeg_quality); + return -1; + } + + if(m_jpeg_quality != jpeg_quality) + { + m_jpeg_quality = jpeg_quality; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAM_JPEG_QUALITY", __FUNCTION__); + return -1; + } + } + + return 0; +} + +int SecCamera::getJpegQuality(void) +{ + return m_jpeg_quality; +} + +//====================================================================== + +int SecCamera::setZoom(int zoom_level) +{ + LOGV("%s(zoom_level (%d))", __FUNCTION__, zoom_level); + + if(zoom_level < ZOOM_LEVEL_0|| ZOOM_LEVEL_MAX<= zoom_level) + { + LOGE("ERR(%s):Invalid zoom_level (%d)", __FUNCTION__, zoom_level); + return -1; + } + + if(m_zoom_level != zoom_level) + { + m_zoom_level = zoom_level; + + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_ZOOM, zoom_level) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_ZOOM", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getZoom(void) +{ + return m_zoom_level; +} + +//====================================================================== + +int SecCamera::setObjectTracking(int object_tracking) +{ + LOGV("%s(object_tracking (%d))", __FUNCTION__, object_tracking); + + if(object_tracking < OBJECT_TRACKING_OFF|| OBJECT_TRACKING_MAX<= object_tracking) + { + LOGE("ERR(%s):Invalid object_tracking (%d)", __FUNCTION__, object_tracking); + return -1; + } + + if(m_object_tracking != object_tracking) + { + m_object_tracking = object_tracking; + } + + return 0; +} + +int SecCamera::getObjectTracking(void) +{ + return m_object_tracking; +} + +int SecCamera::getObjectTrackingStatus(void) +{ + int obj_status = 0; + obj_status = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJ_TRACKING_STATUS); + return obj_status; +} + +int SecCamera::setObjectTrackingStartStop(int start_stop) +{ + LOGV("%s(object_tracking_start_stop (%d))", __FUNCTION__, start_stop); + + if(m_object_tracking_start_stop != start_stop) + { + m_object_tracking_start_stop = start_stop; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP, start_stop) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP", __FUNCTION__); + return -1; + } + } + + return 0; +} + +int SecCamera::setTouchAFStartStop(int start_stop) +{ + LOGV("%s(touch_af_start_stop (%d))", __FUNCTION__, start_stop); + + if(m_touch_af_start_stop != start_stop) + { + m_touch_af_start_stop = start_stop; + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_TOUCH_AF_START_STOP, start_stop) < 0) +{ + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_TOUCH_AF_START_STOP", __FUNCTION__); + return -1; + } + } + + return 0; +} + +//====================================================================== + +int SecCamera::setSmartAuto(int smart_auto) +{ + LOGV("%s(smart_auto (%d))", __FUNCTION__, smart_auto); + + if(smart_auto < SMART_AUTO_OFF|| SMART_AUTO_MAX <= smart_auto) + { + LOGE("ERR(%s):Invalid smart_auto (%d)", __FUNCTION__, smart_auto); + return -1; + } + + if(m_smart_auto != smart_auto) + { + m_smart_auto = smart_auto; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SMART_AUTO, smart_auto) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SMART_AUTO", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getSmartAuto(void) +{ + return m_smart_auto; +} + +int SecCamera::getAutosceneStatus(void) +{ + int autoscene_status = -1; + + if(getSmartAuto() == SMART_AUTO_ON) + { + autoscene_status = fimc_v4l2_g_ctrl(m_cam_fd, V4L2_CID_CAMERA_SMART_AUTO_STATUS); + + if((autoscene_status < SMART_AUTO_STATUS_AUTO) || (autoscene_status > SMART_AUTO_STATUS_MAX)) + { + LOGE("ERR(%s):Invalid getAutosceneStatus (%d)", __FUNCTION__, autoscene_status); + return -1; + } + } + //LOGV("%s() autoscene_status (%d)", __FUNCTION__, autoscene_status); + return autoscene_status; +} +//====================================================================== + +int SecCamera::setBeautyShot(int beauty_shot) +{ + LOGV("%s(beauty_shot (%d))", __FUNCTION__, beauty_shot); + + if(beauty_shot < BEAUTY_SHOT_OFF|| BEAUTY_SHOT_MAX <= beauty_shot) + { + LOGE("ERR(%s):Invalid beauty_shot (%d)", __FUNCTION__, beauty_shot); + return -1; + } + + if(m_beauty_shot != beauty_shot) + { + m_beauty_shot = beauty_shot; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BEAUTY_SHOT, beauty_shot) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BEAUTY_SHOT", __FUNCTION__); + return -1; + } + + setFaceDetect(FACE_DETECT_BEAUTY_ON); + } + } + + return 0; +} + +int SecCamera::getBeautyShot(void) +{ + return m_beauty_shot; +} + +//====================================================================== + +int SecCamera::setVintageMode(int vintage_mode) +{ + LOGV("%s(vintage_mode(%d))", __FUNCTION__, vintage_mode); + + if(vintage_mode <= VINTAGE_MODE_BASE || VINTAGE_MODE_MAX <= vintage_mode) + { + LOGE("ERR(%s):Invalid vintage_mode (%d)", __FUNCTION__, vintage_mode); + return -1; + } + + if(m_vintage_mode != vintage_mode) + { + m_vintage_mode = vintage_mode; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_VINTAGE_MODE, vintage_mode) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_VINTAGE_MODE", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + +int SecCamera::getVintageMode(void) +{ + return m_vintage_mode; +} + +//====================================================================== + +int SecCamera::setFocusMode(int focus_mode) +{ + LOGV("%s(focus_mode(%d))", __FUNCTION__, focus_mode); + + if(FOCUS_MODE_MAX <= focus_mode) + { + LOGE("ERR(%s):Invalid focus_mode (%d)", __FUNCTION__, focus_mode); + return -1; + } + + if(m_focus_mode != focus_mode) + { + m_focus_mode = focus_mode; + + if (m_focus_mode != FOCUS_MODE_FACEDETECT) + { + m_face_detect = FACE_DETECT_OFF; + if(m_flag_camera_start) + { +// setFaceDetect(m_face_detect); + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __FUNCTION__); + return -1; + } + } + } + else + { + m_face_detect = FACE_DETECT_NORMAL_ON; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_AUTO) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODE", __FUNCTION__); + return -1; + } + +// setFaceDetect(m_face_detect); + } + } + } + + return 0; +} + +int SecCamera::getFocusMode(void) +{ + return m_focus_mode; +} + +//====================================================================== + + int SecCamera::setFaceDetect(int face_detect) + { + LOGV("%s(face_detect(%d))", __FUNCTION__, face_detect); + +// if(m_face_detect != face_detect) + { + m_face_detect = face_detect; + if(m_flag_camera_start) + { + if(m_face_detect != FACE_DETECT_OFF) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FOCUS_MODE, FOCUS_MODE_AUTO) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FOCUS_MODin face detecion", __FUNCTION__); + return -1; + } + } + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FACE_DETECTION, face_detect) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACE_DETECTION", __FUNCTION__); + return -1; + } + } + } + + return 0; +} + + int SecCamera::getFaceDetect(void) + { + return m_face_detect; + } + + //====================================================================== + + int SecCamera::setGPSLatitude(const char * gps_latitude) + { + double conveted_latitude = 0; + LOGV("%s(gps_latitude(%s))", __FUNCTION__, gps_latitude); + if(gps_latitude == NULL) + m_gps_latitude = 0; + else + { + conveted_latitude = atof(gps_latitude); + m_gps_latitude = (long)(conveted_latitude *10000 /1); + } + + LOGV("%s(m_gps_latitude(%ld))", __FUNCTION__, m_gps_latitude); + return 0; + } + int SecCamera::setGPSLongitude(const char * gps_longitude) + { + double conveted_longitude = 0; + LOGV("%s(gps_longitude(%s))", __FUNCTION__, gps_longitude); + if(gps_longitude == NULL) + m_gps_longitude = 0; + else + { + conveted_longitude = atof(gps_longitude); + m_gps_longitude = (long)(conveted_longitude *10000 /1); + } + + LOGV("%s(m_gps_longitude(%ld))", __FUNCTION__, m_gps_longitude); + return 0; + } + int SecCamera::setGPSAltitude(const char * gps_altitude) + { + double conveted_altitude = 0; + LOGV("%s(gps_altitude(%s))", __FUNCTION__, gps_altitude); + if(gps_altitude == NULL) + m_gps_altitude = 0; + else + { + conveted_altitude = atof(gps_altitude); + m_gps_altitude = (long)(conveted_altitude *100 /1); + } + + LOGV("%s(m_gps_altitude(%ld))", __FUNCTION__, m_gps_altitude); + return 0; + } + int SecCamera::setGPSTimeStamp(const char * gps_timestamp) + { + LOGV("%s(gps_timestamp(%s))", __FUNCTION__, gps_timestamp); + if(gps_timestamp == NULL) + m_gps_timestamp = 0; + else + m_gps_timestamp = atol(gps_timestamp); + + LOGV("%s(m_gps_timestamp(%ld))", __FUNCTION__, m_gps_timestamp); + return 0; + } + + //====================================================================== + int SecCamera::setAEAWBLockUnlock(int ae_lockunlock, int awb_lockunlock) + { + LOGV("%s(ae_lockunlock(%d) , (awb_lockunlock(%d))", __FUNCTION__, ae_lockunlock, awb_lockunlock); + int ae_awb_status = 1; +#if 0 + if(ae_lockunlock == 0 && awb_lockunlock ==0) + ae_awb_status = AE_UNLOCK_AWB_UNLOCK; + else if (ae_lockunlock == 1 && awb_lockunlock ==0) + ae_awb_status = AE_LOCK_AWB_UNLOCK; + else if (ae_lockunlock == 1 && awb_lockunlock ==0) + ae_awb_status = AE_UNLOCK_AWB_LOCK; + else + ae_awb_status = AE_LOCK_AWB_LOCK; +#endif + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, ae_awb_status) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_AE_AWB_LOCKUNLOCK", __FUNCTION__); + return -1; + } + + return 0; + } + + int SecCamera::setFaceDetectLockUnlock(int facedetect_lockunlock) + { + LOGV("%s(facedetect_lockunlock(%d))", __FUNCTION__, facedetect_lockunlock); + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK, facedetect_lockunlock) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK", __FUNCTION__); + return -1; + } + + return 0; + } + + int SecCamera::setObjectPosition(int x, int y) + { + LOGV("%s(setObjectPosition(x=%d, y=%d))", __FUNCTION__, x, y); + + if(m_preview_width ==640) + x = x - 80; + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJECT_POSITION_X, x) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_X", __FUNCTION__); + return -1; + } + + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_OBJECT_POSITION_Y, y) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_OBJECT_POSITION_Y", __FUNCTION__); + return -1; + } + + return 0; + } + + //====================================================================== + + int SecCamera::setGamma(int gamma) + { + LOGV("%s(gamma(%d))", __FUNCTION__, gamma); + + if(gamma<GAMMA_OFF|| GAMMA_MAX<= gamma) + { + LOGE("ERR(%s):Invalid gamma (%d)", __FUNCTION__, gamma); + return -1; + } + + if(m_video_gamma!= gamma) + { + m_video_gamma = gamma; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_GAMMA, gamma) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_GAMMA", __FUNCTION__); + return -1; + } + } + } + + return 0; + } + + //====================================================================== + + int SecCamera::setSlowAE(int slow_ae) + { + LOGV("%s(slow_ae(%d))", __FUNCTION__, slow_ae); + + if(slow_ae<GAMMA_OFF|| GAMMA_MAX<= slow_ae) + { + LOGE("ERR(%s):Invalid slow_ae (%d)", __FUNCTION__, slow_ae); + return -1; + } + + if(m_slow_ae!= slow_ae) + { + m_slow_ae = slow_ae; + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_SET_SLOW_AE, slow_ae) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_SET_SLOW_AE", __FUNCTION__); + return -1; + } + } + } + + return 0; + } + + //====================================================================== + + int SecCamera::setRecordingSize(int width, int height) + { + LOGE("%s(width(%d), height(%d))", __FUNCTION__, width, height); + + m_recording_width = width; + m_recording_height = height; + + return 0; + } + + //====================================================================== + +int SecCamera::setExifOrientationInfo(int orientationInfo) +{ + LOGV("%s(orientationInfo(%d))", __FUNCTION__, orientationInfo); + + if(orientationInfo < 0) + { + LOGE("ERR(%s):Invalid orientationInfo (%d)", __FUNCTION__, orientationInfo); + return -1; + } + m_exif_orientation = orientationInfo; + + return 0; +} + + //====================================================================== +int SecCamera::setBatchReflection() +{ + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_BATCH_REFLECTION, 1) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_BATCH_REFLECTION", __FUNCTION__); + return -1; + } + } + + return 0; +} + +/*Video call*/ +int SecCamera::setVTmode(int vtmode) +{ + LOGV("%s(vtmode (%d))", __FUNCTION__, vtmode); + + if(vtmode < VT_MODE_OFF || VT_MODE_MAX <= vtmode) + { + LOGE("ERR(%s):Invalid vtmode (%d)", __FUNCTION__, vtmode); + return -1; + } + + if(m_vtmode != vtmode) + { + m_vtmode = vtmode; + } + + return 0; +} + +/* Camcorder fix fps */ +int SecCamera::setSensorMode(int sensor_mode) +{ + LOGV("%s(sensor_mode (%d))", __FUNCTION__, sensor_mode); + + if(sensor_mode < SENSOR_MODE_CAMERA || SENSOR_MODE_MOVIE < sensor_mode) + { + LOGE("ERR(%s):Invalid sensor mode (%d)", __FUNCTION__, sensor_mode); + return -1; + } + + if(m_sensor_mode != sensor_mode) + { + m_sensor_mode = sensor_mode; + } + + return 0; +} + +/* Shot mode */ +/* SINGLE = 0 +* CONTINUOUS = 1 +* PANORAMA = 2 +* SMILE = 3 +* SELF = 6 +*/ +int SecCamera::setShotMode(int shot_mode) +{ + LOGV("%s(shot_mode (%d))", __FUNCTION__, shot_mode); + if(shot_mode < SHOT_MODE_SINGLE || SHOT_MODE_SELF < shot_mode) + { + LOGE("ERR(%s):Invalid shot_mode (%d)", __FUNCTION__, shot_mode); + return -1; + } + m_shot_mode = shot_mode; + + return 0; +} + +int SecCamera::getVTmode(void) +{ + return m_vtmode; +} + +int SecCamera::setBlur(int blur_level) +{ + LOGV("%s(level (%d))", __FUNCTION__, blur_level); + + if(blur_level < BLUR_LEVEL_0|| BLUR_LEVEL_MAX <= blur_level) + { + LOGE("ERR(%s):Invalid level (%d)", __FUNCTION__, blur_level); + return -1; + } + + if(m_blur_level != blur_level) + { + m_blur_level = blur_level; + + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_VGA_BLUR, blur_level) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_VGA_BLUR", __FUNCTION__); + return -1; + } + } + } + return 0; +} + +int SecCamera::getBlur(void) +{ + return m_blur_level; +} + + +int SecCamera::setDataLineCheck(int chk_dataline) +{ + LOGV("%s(chk_dataline (%d))", __FUNCTION__, chk_dataline); + + if(chk_dataline < CHK_DATALINE_OFF || CHK_DATALINE_MAX<= chk_dataline) + { + LOGE("ERR(%s):Invalid chk_dataline (%d)", __FUNCTION__, chk_dataline); + return -1; + } + + if(m_chk_dataline != chk_dataline) + { + m_chk_dataline = chk_dataline; + } + + return 0; +} + +int SecCamera::getDataLineCheck(void) +{ + return m_chk_dataline; +} + +int SecCamera::setDataLineCheckStop(void) +{ + LOGV("%s", __FUNCTION__); + + if(m_flag_camera_start) + { + if (fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_CHECK_DATALINE_STOP, 1) < 0) + { + LOGE("ERR(%s):Fail on V4L2_CID_CAMERA_CHECK_DATALINE_STOP", __FUNCTION__); + return -1; + } + } + return 0; +} + +#endif + +// ====================================================================== +// Jpeg + +#ifndef JPEG_FROM_SENSOR +unsigned char * SecCamera::getJpeg(unsigned char *snapshot_data, int snapshot_size, int * size) +{ + LOGV("%s()", __FUNCTION__); + + if(m_cam_fd <= 0) + { + LOGE("ERR(%s):Camera was closed\n", __FUNCTION__); + return NULL; + } + + unsigned char * jpeg_data = NULL; + int jpeg_size = 0; + + jpeg_data = yuv2Jpeg(snapshot_data, snapshot_size, &jpeg_size, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); + + *size = jpeg_size; + return jpeg_data; +} +#endif + +#ifndef JPEG_FROM_SENSOR +unsigned char * SecCamera::yuv2Jpeg(unsigned char * raw_data, int raw_size,int * jpeg_size,int width, int height, int pixel_format) +{ + LOGV("%s:raw_data(%p), raw_size(%d), jpeg_size(%d), width(%d), height(%d), format(%d)", + __FUNCTION__, raw_data, raw_size, *jpeg_size, width, height, pixel_format); + + if(m_jpeg_fd <= 0) + { + LOGE("ERR(%s):JPEG device was closed\n", __FUNCTION__); + return NULL; + } + if(pixel_format == V4L2_PIX_FMT_RGB565) + { + LOGE("ERR(%s):It doesn't support V4L2_PIX_FMT_RGB565\n", __FUNCTION__); + return NULL; + } + + unsigned char * InBuf = NULL; + unsigned char * OutBuf = NULL; + unsigned char * jpeg_data = NULL; + long frameSize; + exif_file_info_t ExifInfo; + + int input_file_format = JPG_MODESEL_YCBCR; + + int out_file_format = JPG_422; + switch(pixel_format) + { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + out_file_format = JPG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + out_file_format = JPG_422; + break; + } + + ////////////////////////////////////////////////////////////// + // 2. set encode config. // + ////////////////////////////////////////////////////////////// + LOGV("Step 1 : JPEG_SET_ENCODE_IN_FORMAT(JPG_MODESEL_YCBCR)"); + if (SsbSipJPEGSetEncConfig(JPEG_SET_ENCODE_IN_FORMAT, input_file_format) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_ENCODE_IN_FORMAT\n", __FUNCTION__); + goto YUV2JPEG_END; + } + + LOGV("Step 2 : JPEG_SET_SAMPING_MODE(JPG_422)"); + if (SsbSipJPEGSetEncConfig(JPEG_SET_SAMPING_MODE, out_file_format) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_SAMPING_MODE\n", __FUNCTION__); + goto YUV2JPEG_END; + } + + LOGV("Step 3 : JPEG_SET_ENCODE_WIDTH(%d)", width); + if (SsbSipJPEGSetEncConfig(JPEG_SET_ENCODE_WIDTH, width) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_ENCODE_WIDTH \n", __FUNCTION__); + goto YUV2JPEG_END; + } + + LOGV("Step 4 : JPEG_SET_ENCODE_HEIGHT(%d)", height); + if (SsbSipJPEGSetEncConfig(JPEG_SET_ENCODE_HEIGHT, height) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_ENCODE_HEIGHT \n", __FUNCTION__); + goto YUV2JPEG_END; + } + + LOGV("Step 5 : JPEG_SET_ENCODE_QUALITY(JPG_QUALITY_LEVEL_2)"); + if (SsbSipJPEGSetEncConfig(JPEG_SET_ENCODE_QUALITY, JPG_QUALITY_LEVEL_2) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_ENCODE_QUALITY \n", __FUNCTION__); + goto YUV2JPEG_END; + } + +#if (INCLUDE_JPEG_THUMBNAIL == 1) + + LOGV("Step 6a : JPEG_SET_ENCODE_THUMBNAIL(TRUE)"); + if (SsbSipJPEGSetEncConfig(JPEG_SET_ENCODE_THUMBNAIL, TRUE) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_ENCODE_THUMBNAIL \n", __FUNCTION__); + goto YUV2JPEG_END; + } + + LOGV("Step 6b : JPEG_SET_THUMBNAIL_WIDTH(%d)", m_jpeg_thumbnail_width); + if (SsbSipJPEGSetEncConfig(JPEG_SET_THUMBNAIL_WIDTH, m_jpeg_thumbnail_width) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_THUMBNAIL_WIDTH(%d) \n", __FUNCTION__, m_jpeg_thumbnail_height); + goto YUV2JPEG_END; + } + + LOGV("Step 6c : JPEG_SET_THUMBNAIL_HEIGHT(%d)", m_jpeg_thumbnail_height); + if (SsbSipJPEGSetEncConfig(JPEG_SET_THUMBNAIL_HEIGHT, m_jpeg_thumbnail_height) != JPEG_OK) { + LOGE("ERR(%s):Fail on JPEG_SET_THUMBNAIL_HEIGHT(%d) \n", __FUNCTION__, m_jpeg_thumbnail_height); + goto YUV2JPEG_END; + } + +#endif + + if(raw_size == 0) //Kamat: This is our code path + { + unsigned int addr_y; + int width, height,frame_size; + getSnapshotSize(&width, &height, &frame_size); + if(raw_data == NULL) + { + LOGE("%s %d] Raw data is NULL \n",__func__,__LINE__); + goto YUV2JPEG_END; + } + else //Kamat: our path + { + addr_y = (unsigned int)raw_data; + } + + SsbSipJPEGSetEncodeInBuf(m_jpeg_fd, addr_y, frame_size); + } + else + { + ////////////////////////////////////////////////////////////// + // 4. get Input buffer address // + ////////////////////////////////////////////////////////////// + LOGV("Step 7 : Input buffer size(0x%X", raw_size); + InBuf = (unsigned char *)SsbSipJPEGGetEncodeInBuf(m_jpeg_fd, raw_size); + if(InBuf == NULL) + { + LOGE("ERR(%s):Fail on SsbSipJPEGGetEncodeInBuf \n", __FUNCTION__); + goto YUV2JPEG_END; + } + ////////////////////////////////////////////////////////////// + // 5. put YUV stream to Input buffer + ////////////////////////////////////////////////////////////// + LOGV("Step 8: memcpy(InBuf(%p), raw_data(%p), raw_size(%d)", InBuf, raw_data, raw_size); + memcpy(InBuf, raw_data, raw_size); + } + + ////////////////////////////////////////////////////////////// + // 6. Make Exif info parameters + ////////////////////////////////////////////////////////////// + LOGV("Step 9: m_makeExifParam()"); + memset(&ExifInfo, 0x00, sizeof(exif_file_info_t)); + m_makeExifParam(&ExifInfo); + + ////////////////////////////////////////////////////////////// + // 7. Encode YUV stream + ////////////////////////////////////////////////////////////// + LOGV("Step a: SsbSipJPEGEncodeExe()"); + if(SsbSipJPEGEncodeExe(m_jpeg_fd, &ExifInfo, JPEG_USE_SW_SCALER) != JPEG_OK) //with Exif + { + LOGE("ERR(%s):Fail on SsbSipJPEGEncodeExe \n", __FUNCTION__); + goto YUV2JPEG_END; + } + ////////////////////////////////////////////////////////////// + // 8. get output buffer address + ////////////////////////////////////////////////////////////// + LOGV("Step b: SsbSipJPEGGetEncodeOutBuf()"); + OutBuf = (unsigned char *)SsbSipJPEGGetEncodeOutBuf(m_jpeg_fd, &frameSize); + if(OutBuf == NULL) + { + LOGE("ERR(%s):Fail on SsbSipJPEGGetEncodeOutBuf \n", __FUNCTION__); + goto YUV2JPEG_END; + } + ////////////////////////////////////////////////////////////// + // 9. write JPEG result file + ////////////////////////////////////////////////////////////// + LOGV("Done"); + jpeg_data = OutBuf; + *jpeg_size = (int)frameSize; + +YUV2JPEG_END : + + return jpeg_data; +} +#endif + +int SecCamera::setJpegThumbnailSize(int width, int height) +{ + LOGV("%s(width(%d), height(%d))", __FUNCTION__, width, height); + + m_jpeg_thumbnail_width = width; + m_jpeg_thumbnail_height = height; + + return 0; +} + +int SecCamera::getJpegThumbnailSize(int * width, int * height) +{ + if(width) + *width = m_jpeg_thumbnail_width; + if(height) + *height = m_jpeg_thumbnail_height; + + return 0; +} + +void SecCamera::setExifFixedAttribute() +{ + //2 0th IFD TIFF Tags + //3 Maker + strcpy((char *)mExifInfo.maker, EXIF_DEF_MAKER); + //3 Model + strcpy((char *)mExifInfo.model, EXIF_DEF_MODEL); + //3 Software + property_get("ro.build.PDA", (char *)mExifInfo.software, EXIF_DEF_SOFTWARE); + //3 YCbCr Positioning + mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING; + + //2 0th IFD Exif Private Tags + //3 F Number + mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM; + mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN; + //3 Exposure Program + mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM; + //3 Exif Version + memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version)); + //3 Aperture + uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); + mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN; + mExifInfo.aperture.den = EXIF_DEF_APEX_DEN; + //3 Maximum lens aperture + mExifInfo.max_aperture.num = mExifInfo.aperture.num; + mExifInfo.max_aperture.den = mExifInfo.aperture.den; + //3 Flash + mExifInfo.flash = EXIF_DEF_FLASH; + //3 Lens Focal Length + mExifInfo.focal_length.num = EXIF_DEF_FOCAL_LEN_NUM; + mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; + //3 User Comments + strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS); + //3 Color Space information + mExifInfo.color_space = EXIF_DEF_COLOR_SPACE; + //3 Exposure Mode + mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE; + + //2 0th IFD GPS Info Tags + unsigned char gps_version[4] = {0x02, 0x02, 0x00, 0x00}; + memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version)); + + //2 1th IFD TIFF Tags + mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION; + mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT; +} + +void SecCamera::setExifChangedAttribute() +{ + //2 0th IFD TIFF Tags + //3 Width + mExifInfo.width = m_snapshot_width; + //3 Height + mExifInfo.height = m_snapshot_height; + //3 Orientation + switch(m_exif_orientation) { + case 0: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + case 90: + mExifInfo.orientation = EXIF_ORIENTATION_90; + break; + case 180: + mExifInfo.orientation = EXIF_ORIENTATION_180; + break; + case 270: + mExifInfo.orientation = EXIF_ORIENTATION_270; + break; + default: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + } + //3 Date time + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo); + + //2 0th IFD Exif Private Tags + //3 Exposure Time + int shutterSpeed = fimc_v4l2_s_ctrl(m_cam_fd, + V4L2_CID_CAMERA_GET_SHT_TIME, + 0); + mExifInfo.exposure_time.num = 1; + mExifInfo.exposure_time.den = 1000000.0/shutterSpeed; /* us -> sec */ + + //3 ISO Speed Rating + int iso = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_GET_ISO, 0); + if (m_iso == ISO_AUTO) { + mExifInfo.iso_speed_rating = iso; + } + else { + switch(m_iso) { + case ISO_50: + mExifInfo.iso_speed_rating = 50; + break; + case ISO_100: + mExifInfo.iso_speed_rating = 100; + break; + case ISO_200: + mExifInfo.iso_speed_rating = 200; + break; + case ISO_400: + mExifInfo.iso_speed_rating = 400; + break; + case ISO_800: + mExifInfo.iso_speed_rating = 800; + break; + case ISO_1600: + mExifInfo.iso_speed_rating = 1600; + break; + default: + mExifInfo.iso_speed_rating = iso; + break; + } + } + + uint32_t av, tv, bv, sv, ev; + av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double)mExifInfo.exposure_time.num/mExifInfo.exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(iso); + bv = av + tv - sv; + ev = av + tv; + LOGD("Shutter speed=%d us, iso=%d\n", shutterSpeed, iso); + LOGD("AV=%d, TV=%d, SV=%d\n", av, tv, sv); + + //3 Shutter Speed + mExifInfo.shutter_speed.num = tv*EXIF_DEF_APEX_DEN; + mExifInfo.shutter_speed.den = EXIF_DEF_APEX_DEN; + //3 Brightness + mExifInfo.brightness.num = bv*EXIF_DEF_APEX_DEN; + mExifInfo.brightness.den = EXIF_DEF_APEX_DEN; + //3 Exposure Bias + if (m_scene_mode == SCENE_MODE_BEACH_SNOW) { + mExifInfo.exposure_bias.num = 1*EXIF_DEF_APEX_DEN; + mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN; + } + else { + mExifInfo.exposure_bias.num = 0; + mExifInfo.exposure_bias.den = 0; + } + //3 Metering Mode + switch(m_metering) { + case METERING_SPOT: + mExifInfo.metering_mode = EXIF_METERING_SPOT; + break; + case METERING_MATRIX: + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + case METERING_CENTER: + mExifInfo.metering_mode = EXIF_METERING_CENTER; + break; + default : + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + } + //3 White Balance + if(m_white_balance == WHITE_BALANCE_AUTO) + mExifInfo.white_balance = EXIF_WB_AUTO; + else + mExifInfo.white_balance = EXIF_WB_MANUAL; + //3 Scene Capture Type + switch(m_scene_mode) { + case SCENE_MODE_PORTRAIT: + mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT; + break; + case SCENE_MODE_LANDSCAPE: + mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE; + break; + case SCENE_MODE_NIGHTSHOT: + mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT; + break; + default: + mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD; + break; + } + + //2 0th IFD GPS Info Tags + if (m_gps_latitude != 0 && m_gps_longitude != 0) { + if (m_gps_latitude > 0) + strcpy((char *)mExifInfo.gps_latitude_ref, "N"); + else + strcpy((char *)mExifInfo.gps_latitude_ref, "S"); + + if (m_gps_longitude > 0) + strcpy((char *)mExifInfo.gps_longitude_ref, "E"); + else + strcpy((char *)mExifInfo.gps_longitude_ref, "W"); + + if (m_gps_altitude > 0) + mExifInfo.gps_altitude_ref = 0; + else + mExifInfo.gps_altitude_ref = 1; + + double latitude = fabs(m_gps_latitude/10000.0); + double longitude = fabs(m_gps_longitude/10000.0); + double altitude = fabs(m_gps_altitude/100.0); + + mExifInfo.gps_latitude[0].num = (uint32_t)latitude; + mExifInfo.gps_latitude[0].den = 1; + mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60); + mExifInfo.gps_latitude[1].den = 1; + mExifInfo.gps_latitude[2].num = (uint32_t)((((latitude - mExifInfo.gps_latitude[0].num) * 60) + - mExifInfo.gps_latitude[1].num) * 60); + mExifInfo.gps_latitude[2].den = 1; + + mExifInfo.gps_longitude[0].num = (uint32_t)longitude; + mExifInfo.gps_longitude[0].den = 1; + mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60); + mExifInfo.gps_longitude[1].den = 1; + mExifInfo.gps_longitude[2].num = (uint32_t)((((longitude - mExifInfo.gps_longitude[0].num) * 60) + - mExifInfo.gps_longitude[1].num) * 60); + mExifInfo.gps_longitude[2].den = 1; + + mExifInfo.gps_altitude.num = (uint32_t)altitude; + mExifInfo.gps_altitude.den = 1; + + mExifInfo.enableGps = true; + } + else { + mExifInfo.enableGps = false; + } + + //2 1th IFD TIFF Tags + int thumbWidth, thumbHeight, thumbSrcSize; + getPostViewConfig(&thumbWidth, &thumbHeight, &thumbSrcSize); + mExifInfo.widthThumb = thumbWidth; + mExifInfo.heightThumb = thumbHeight; +} + +// ====================================================================== +// Conversions + +inline int SecCamera::m_frameSize(int format, int width, int height) +{ + int size = 0; + + switch(format) + { + case V4L2_PIX_FMT_YUV420 : + case V4L2_PIX_FMT_NV12 : + case V4L2_PIX_FMT_NV21 : + size = (width * height * 3 / 2); + break; + + case V4L2_PIX_FMT_NV12T: + size = ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)) + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height/2)); + break; + + case V4L2_PIX_FMT_YUV422P : + case V4L2_PIX_FMT_YUYV : + case V4L2_PIX_FMT_UYVY : + size = (width * height * 2); + break; + + default : + LOGE("ERR(%s):Invalid V4L2 pixel format(%d)\n", __FUNCTION__, format); + case V4L2_PIX_FMT_RGB565 : + size = (width * height * BPP); + break; + } + + return size; +} + +status_t SecCamera::dump(int fd, const Vector<String16>& args) +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + snprintf(buffer, 255, "dump(%d)\n", fd); + result.append(buffer); + ::write(fd, result.string(), result.size()); + return NO_ERROR; +} + +}; // namespace android diff --git a/libcamera/SecCamera.h b/libcamera/SecCamera.h new file mode 100644 index 0000000..e504ca6 --- /dev/null +++ b/libcamera/SecCamera.h @@ -0,0 +1,886 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** +** 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 on 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. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_SEC_H +#define ANDROID_HARDWARE_CAMERA_SEC_H + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <signal.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <sys/stat.h> + +#include <linux/videodev2.h> +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +#include <videodev2_samsung.h> +#endif + +#include "JpegEncoder.h" + +#ifdef ENABLE_HDMI_DISPLAY +#include "hdmi_lib.h" +#endif + +#include <camera/CameraHardwareInterface.h> + +namespace android { + +#define PREVIEW_USING_MMAP //Define this if the preview data is to be shared using memory mapped technique instead of passing physical address. + +#define JPEG_FROM_SENSOR //Define this if the JPEG images are obtained directly from camera sensor. Else on chip JPEG encoder will be used. + +//#define DUAL_PORT_RECORDING //Define this if 2 fimc ports are needed for recording. + +//#define SEND_YUV_RECORD_DATA //Define this to copy YUV data to encoder instead of sharing the physical address. + +#define INCLUDE_JPEG_THUMBNAIL 1 //Valid only for on chip JPEG encoder + +#if defined PREVIEW_USING_MMAP +#define DUAL_PORT_RECORDING +#endif + +#if defined JPEG_FROM_SENSOR +#define DIRECT_DELIVERY_OF_POSTVIEW_DATA //Define this if postview data is needed in buffer instead of zero copy. +#endif + +#if defined(LOG_NDEBUG) && LOG_NDEBUG == 0 +#define LOG_CAMERA LOGD +#define LOG_CAMERA_PREVIEW LOGD + +#define LOG_TIME_DEFINE(n) \ + struct timeval time_start_##n, time_stop_##n; unsigned long log_time_##n = 0; + +#define LOG_TIME_START(n) \ + gettimeofday(&time_start_##n, NULL); + +#define LOG_TIME_END(n) \ + gettimeofday(&time_stop_##n, NULL); log_time_##n = measure_time(&time_start_##n, &time_stop_##n); + +#define LOG_TIME(n) \ + log_time_##n + +#else +#define LOG_CAMERA(...) +#define LOG_CAMERA_PREVIEW(...) +#define LOG_TIME_DEFINE(n) +#define LOG_TIME_START(n) +#define LOG_TIME_END(n) +#define LOG_TIME(n) +#endif + +#define LCD_WIDTH 480 +#define LCD_HEIGHT 800 + +#define JOIN(x, y) JOIN_AGAIN(x, y) +#define JOIN_AGAIN(x, y) x ## y + +#define FRONT_CAM VGA +#define BACK_CAM CE147 + +#if !defined (FRONT_CAM) || !defined(BACK_CAM) +#error "Please define the Camera module" +#endif + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +#define CE147_PREVIEW_WIDTH 640 +#define CE147_PREVIEW_HEIGHT 480 +#define CE147_SNAPSHOT_WIDTH 2560 +#define CE147_SNAPSHOT_HEIGHT 1920 +#else +#define CE147_PREVIEW_WIDTH 1280 +#define CE147_PREVIEW_HEIGHT 720 +#define CE147_SNAPSHOT_WIDTH 2592 +#define CE147_SNAPSHOT_HEIGHT 1936 +#endif + +#define CE147_POSTVIEW_WIDTH 640 +#define CE147_POSTVIEW_WIDE_WIDTH 800 +#define CE147_POSTVIEW_HEIGHT 480 +#define CE147_POSTVIEW_BPP 16 + +#define VGA_PREVIEW_WIDTH 640 +#define VGA_PREVIEW_HEIGHT 480 +#define VGA_SNAPSHOT_WIDTH 640 +#define VGA_SNAPSHOT_HEIGHT 480 + +#define MAX_BACK_CAMERA_PREVIEW_WIDTH JOIN(BACK_CAM,_PREVIEW_WIDTH) +#define MAX_BACK_CAMERA_PREVIEW_HEIGHT JOIN(BACK_CAM,_PREVIEW_HEIGHT) +#define MAX_BACK_CAMERA_SNAPSHOT_WIDTH JOIN(BACK_CAM,_SNAPSHOT_WIDTH) +#define MAX_BACK_CAMERA_SNAPSHOT_HEIGHT JOIN(BACK_CAM,_SNAPSHOT_HEIGHT) +#define BACK_CAMERA_POSTVIEW_WIDTH JOIN(BACK_CAM,_POSTVIEW_WIDTH) +#define BACK_CAMERA_POSTVIEW_WIDE_WIDTH JOIN(BACK_CAM,_POSTVIEW_WIDE_WIDTH) +#define BACK_CAMERA_POSTVIEW_HEIGHT JOIN(BACK_CAM,_POSTVIEW_HEIGHT) +#define BACK_CAMERA_POSTVIEW_BPP JOIN(BACK_CAM,_POSTVIEW_BPP) + +#define MAX_FRONT_CAMERA_PREVIEW_WIDTH JOIN(FRONT_CAM,_PREVIEW_WIDTH) +#define MAX_FRONT_CAMERA_PREVIEW_HEIGHT JOIN(FRONT_CAM,_PREVIEW_HEIGHT) +#define MAX_FRONT_CAMERA_SNAPSHOT_WIDTH JOIN(FRONT_CAM,_SNAPSHOT_WIDTH) +#define MAX_FRONT_CAMERA_SNAPSHOT_HEIGHT JOIN(FRONT_CAM,_SNAPSHOT_HEIGHT) + +#define DEFAULT_JPEG_THUMBNAIL_WIDTH 256 +#define DEFAULT_JPEG_THUMBNAIL_HEIGHT 192 + +#define CAMERA_DEV_NAME "/dev/video0" + +#ifdef DUAL_PORT_RECORDING +#define CAMERA_DEV_NAME2 "/dev/video2" +#endif +#define CAMERA_DEV_NAME_TEMP "/data/videotmp_000" +#define CAMERA_DEV_NAME2_TEMP "/data/videotemp_002" + + +#define BPP 2 +#define MIN(x, y) ((x < y) ? x : y) +#define MAX_BUFFERS 8 + +/* + * 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 TPATTERN_COLORBAR 1 +#define TPATTERN_HORIZONTAL 2 +#define TPATTERN_VERTICAL 3 + +#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') +/* + * U S E R D E F I N E D T Y P E S + * +*/ + +struct fimc_buffer { + void *start; + size_t length; +}; + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int depth; + int planes; +}; + +//s1 [Apply factory standard] +struct camsensor_date_info { + unsigned int year; + unsigned int month; + unsigned int date; +}; + + +class SecCamera { +public: + + enum CAMERA_ID + { + CAMERA_ID_BACK = 1, + CAMERA_ID_FRONT = 2, + }; + + enum AUTO_FOCUS + { + AUTO_FOCUS_OFF, + AUTO_FOCUS_ON, + AUTO_FOCUS_STATUS, + }; + + enum WHILTE_BALANCE + { + #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + WHITE_BALANCE_BASE, + WHITE_BALANCE_AUTO, + WHITE_BALANCE_DAYLIGHT, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_INCANDESCENT, + WHITE_BALANCE_FLUORESCENT, + WHITE_BALANCE_MAX, + #else + WHITE_BALANCE_AUTO, + WHITE_BALANCE_INDOOR3100, + WHITE_BALANCE_OUTDOOR5100, + WHITE_BALANCE_INDOOR2000, + WHITE_BALANCE_HALT, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_SUNNY, + #endif + }; + + enum BRIGHTNESS + { + BRIGHTNESS_MINUS_4= 0, + BRIGHTNESS_MINUS_3, + BRIGHTNESS_MINUS_2, + BRIGHTNESS_MINUS_1, + BRIGHTNESS_NORMAL, + BRIGHTNESS_PLUS_1, + BRIGHTNESS_PLUS_2, + BRIGHTNESS_PLUS_3, + BRIGHTNESS_PLUS_4, + }; + + enum IMAGE_EFFECT + { + #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + IMAGE_EFFECT_BASE, + IMAGE_EFFECT_NONE, + IMAGE_EFFECT_BNW, + IMAGE_EFFECT_SEPIA, + IMAGE_EFFECT_AQUA, + IMAGE_EFFECT_ANTIQUE, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_SHARPEN, + IMAGE_EFFECT_MAX, + #else + IMAGE_EFFECT_ORIGINAL, + IMAGE_EFFECT_ARBITRARY, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_FREEZE, + IMAGE_EFFECT_EMBOSSING, + IMAGE_EFFECT_SILHOUETTE, + #endif + }; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + enum SCENE_MODE + { + SCENE_MODE_BASE, + SCENE_MODE_NONE, + SCENE_MODE_PORTRAIT, + SCENE_MODE_NIGHTSHOT, + SCENE_MODE_BACK_LIGHT, + SCENE_MODE_LANDSCAPE, + SCENE_MODE_SPORTS, + SCENE_MODE_PARTY_INDOOR, + SCENE_MODE_BEACH_SNOW, + SCENE_MODE_SUNSET, + SCENE_MODE_DUSK_DAWN, + SCENE_MODE_FALL_COLOR, + SCENE_MODE_FIREWORKS, + SCENE_MODE_TEXT, + SCENE_MODE_CANDLE_LIGHT, + SCENE_MODE_MAX, + }; + + enum FLASH_MODE + { + FLASH_MODE_BASE, + FLASH_MODE_OFF, + FLASH_MODE_AUTO, + FLASH_MODE_ON, + FLASH_MODE_TORCH, + FLASH_MODE_MAX, + }; + + enum ISO + { + ISO_AUTO, + ISO_50, + ISO_100, + ISO_200, + ISO_400, + ISO_800, + ISO_1600, + ISO_SPORTS, + ISO_NIGHT, + ISO_MOVIE, + ISO_MAX, + }; + + enum METERING + { + METERING_BASE = 0, + METERING_MATRIX, + METERING_CENTER, + METERING_SPOT, + METERING_MAX, + }; + + enum CONTRAST + { + CONTRAST_MINUS_2 = 0, + CONTRAST_MINUS_1, + CONTRAST_NORMAL, + CONTRAST_PLUS_1, + CONTRAST_PLUS_2, + CONTRAST_MAX, + }; + + enum SATURATION + { + SATURATION_MINUS_2= 0, + SATURATION_MINUS_1, + SATURATION_NORMAL, + SATURATION_PLUS_1, + SATURATION_PLUS_2, + SATURATION_MAX, + }; + + enum SHARPNESS + { + SHARPNESS_MINUS_2 = 0, + SHARPNESS_MINUS_1, + SHARPNESS_NORMAL, + SHARPNESS_PLUS_1, + SHARPNESS_PLUS_2, + SHARPNESS_MAX, + }; + + enum WDR + { + WDR_OFF, + WDR_ON, + WDR_MAX, + }; + + enum ANTI_SHAKE + { + ANTI_SHAKE_OFF, + ANTI_SHAKE_ON, + ANTI_SHAKE_MAX, + }; + + enum JPEG_QUALITY + { + JPEG_QUALITY_ECONOMY = 0, + JPEG_QUALITY_NORMAL = 50, + JPEG_QUALITY_SUPERFINE = 100, + JPEG_QUALITY_MAX, + }; + + enum ZOOM_LEVEL + { + ZOOM_LEVEL_0 = 0, + ZOOM_LEVEL_1, + ZOOM_LEVEL_2, + ZOOM_LEVEL_3, + ZOOM_LEVEL_4, + ZOOM_LEVEL_5, + ZOOM_LEVEL_6, + ZOOM_LEVEL_7, + ZOOM_LEVEL_8, + ZOOM_LEVEL_9, + ZOOM_LEVEL_10, + ZOOM_LEVEL_11, + ZOOM_LEVEL_12, + ZOOM_LEVEL_MAX, + }; + + enum OBJECT_TRACKING + { + OBJECT_TRACKING_OFF, + OBJECT_TRACKING_ON, + OBJECT_TRACKING_MAX, + }; + + enum OBJECT_TRACKING_STAUS + { + OBJECT_TRACKING_STATUS_BASE, + OBJECT_TRACKING_STATUS_PROGRESSING, + OBJECT_TRACKING_STATUS_SUCCESS, + OBJECT_TRACKING_STATUS_FAIL, + OBJECT_TRACKING_STATUS_MISSING, + OBJECT_TRACKING_STATUS_MAX, + }; + + enum SMART_AUTO + { + SMART_AUTO_OFF, + SMART_AUTO_ON, + SMART_AUTO_MAX, + }; + + enum BEAUTY_SHOT + { + BEAUTY_SHOT_OFF, + BEAUTY_SHOT_ON, + BEAUTY_SHOT_MAX, + }; + + enum VINTAGE_MODE + { + VINTAGE_MODE_BASE, + VINTAGE_MODE_OFF, + VINTAGE_MODE_NORMAL, + VINTAGE_MODE_WARM, + VINTAGE_MODE_COOL, + VINTAGE_MODE_BNW, + VINTAGE_MODE_MAX, + }; + + enum FOCUS_MODE + { + FOCUS_MODE_AUTO, + FOCUS_MODE_MACRO, + FOCUS_MODE_FACEDETECT, + FOCUS_MODE_AUTO_DEFAULT, + FOCUS_MODE_MACRO_DEFAULT, + FOCUS_MODE_FACEDETECT_DEFAULT, + FOCUS_MODE_MAX, + }; + + enum FACE_DETECT + { + FACE_DETECT_OFF, + FACE_DETECT_NORMAL_ON, + FACE_DETECT_BEAUTY_ON, + FACE_DETECT_NO_LINE, + FACE_DETECT_MAX, + }; + + enum AE_AWB_LOCK_UNLOCK + { + AE_UNLOCK_AWB_UNLOCK = 0, + AE_LOCK_AWB_UNLOCK, + AE_UNLOCK_AWB_LOCK, + AE_LOCK_AWB_LOCK, + AE_AWB_MAX + }; + + enum FRAME_RATE + { + FRAME_RATE_AUTO = 0, + FRAME_RATE_15 = 15, + FRAME_RATE_30 = 30, + FRAME_RATE_60 = 60, + FRAME_RATE_120 = 120, + FRAME_RATE_MAX + }; + enum ANTI_BANDING + { + ANTI_BANDING_AUTO = 0, + ANTI_BANDING_50HZ = 1, + ANTI_BANDING_60HZ = 2, + ANTI_BANDING_OFF = 3, + }; + + enum SMART_AUTO_SCENE + { + SMART_AUTO_STATUS_AUTO = 0, + SMART_AUTO_STATUS_LANDSCAPE, + SMART_AUTO_STATUS_PORTRAIT, + SMART_AUTO_STATUS_MACRO, + SMART_AUTO_STATUS_NIGHT, + SMART_AUTO_STATUS_PORTRAIT_NIGHT, + SMART_AUTO_STATUS_BACKLIT, + SMART_AUTO_STATUS_PORTRAIT_BACKLIT, + SMART_AUTO_STATUS_ANTISHAKE, + SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE, + SMART_AUTO_STATUS_MAX, + }; + + enum GAMMA + { + GAMMA_OFF, + GAMMA_ON, + GAMMA_MAX, + }; + + enum SLOW_AE + { + SLOW_AE_OFF, + SLOW_AE_ON, + SLOW_AE_MAX, + }; + + /*VT call*/ + enum VT_MODE + { + VT_MODE_OFF, + VT_MODE_ON, + VT_MODE_MAX, + }; + + /*Camera sensor mode - Camcorder fix fps*/ + enum SENSOR_MODE + { + SENSOR_MODE_CAMERA, + SENSOR_MODE_MOVIE, + }; + + /*Camera Shot mode*/ + enum SHOT_MODE + { + SHOT_MODE_SINGLE = 0, + SHOT_MODE_CONTINUOUS = 1, + SHOT_MODE_PANORAMA = 2, + SHOT_MODE_SMILE = 3, + SHOT_MODE_SELF = 6, + }; + + enum BLUR_LEVEL + { + BLUR_LEVEL_0 = 0, + BLUR_LEVEL_1, + BLUR_LEVEL_2, + BLUR_LEVEL_3, + BLUR_LEVEL_MAX, + }; + + enum CHK_DATALINE + { + CHK_DATALINE_OFF, + CHK_DATALINE_ON, + CHK_DATALINE_MAX, + }; + + enum FACE_LOCK + { + FACE_LOCK_OFF, + FACE_LOCK_ON, + FIRST_FACE_TRACKING, + FACE_LOCK_MAX + }; + + int m_touch_af_start_stop; + int m_focus_mode; + int m_iso; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + struct gps_info_latiude { + unsigned int north_south; + unsigned int dgree; + unsigned int minute; + unsigned int second; + }gpsInfoLatitude; + struct gps_info_longitude { + unsigned int east_west; + unsigned int dgree; + unsigned int minute; + unsigned int second; + }gpsInfoLongitude; + struct gps_info_altitude { + unsigned int plus_minus; + unsigned int dgree; + unsigned int minute; + unsigned int second; + }gpsInfoAltitude; +#endif + + +#endif + + SecCamera(); + ~SecCamera(); + + static SecCamera * createInstance(void) + { + static SecCamera singleton; + return &singleton; + } + status_t dump(int fd, const Vector<String16>& args); + + int flagCreate(void) const; + + + int setCameraId(int camera_id); + int getCameraId(void); + + int startPreview(void); + int stopPreview (void); +#ifdef DUAL_PORT_RECORDING + int startRecord(void); + int stopRecord (void); + int getRecord(void); + unsigned int getRecPhyAddrY(int); + unsigned int getRecPhyAddrC(int); +#endif + int flagPreviewStart(void); + // int getPreview (unsigned char * buffer, unsigned int buffer_size); + int getPreview(void); + //int getPreview(int *offset, int *size, unsigned char * buffer, unsigned int buffer_size); + int setPreviewSize(int width, int height, int pixel_format); + int getPreviewSize(int * width, int * height, int * frame_size); + int getPreviewMaxSize(int * width, int * height); + int getPreviewPixelFormat(void); + int setPreviewImage(int index, unsigned char * buffer, int size); + + + int getSnapshot(unsigned char * buffer, unsigned int buffer_size); + int setSnapshotSize(int width, int height); + int getSnapshotSize(int * width, int * height, int * frame_size); + int getSnapshotMaxSize(int * width, int * height); + int setSnapshotPixelFormat(int pixel_format); + int getSnapshotPixelFormat(void); + + unsigned char * getJpeg (unsigned char *snapshot_data, int snapshot_size, int * size); + unsigned char * yuv2Jpeg (unsigned char * raw_data, int raw_size, + int * jpeg_size, + int width, int height, int pixel_format); + + int setJpegThumbnailSize(int width, int height); + int getJpegThumbnailSize(int * width, int * height); + + int setAutofocus(void); + int zoomIn(void); + int zoomOut(void); + + int SetRotate(int angle); + int getRotate(void); + + int setVerticalMirror(void); + int setHorizontalMirror(void); + + int setWhiteBalance(int white_balance); + int getWhiteBalance(void); + + int setBrightness(int brightness); + int getBrightness(void); + + int setImageEffect(int image_effect); + int getImageEffect(void); +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + int setSceneMode(int scene_mode); + int getSceneMode(void); + + int setFlashMode(int flash_mode); + int getFlashMode(void); + + int setMetering(int metering_value); + int getMetering(void); + + int setISO(int iso_value); + int getISO(void); + + int setContrast(int contrast_value); + int getContrast(void); + + int setSaturation(int saturation_value); + int getSaturation(void); + + int setSharpness(int sharpness_value); + int getSharpness(void); + + int setWDR(int wdr_value); + int getWDR(void); + + int setAntiShake(int anti_shake); + int getAntiShake(void); + + int setJpegQuality(int jpeg_qality); + int getJpegQuality(void); + + int setZoom(int zoom_level); + int getZoom(void); + + int setObjectTracking(int object_tracking); + int getObjectTracking(void); + int getObjectTrackingStatus(void); + + int setSmartAuto(int smart_auto); + int getSmartAuto(void); + int getAutosceneStatus(void); + + int setBeautyShot(int beauty_shot); + int getBeautyShot(void); + + int setVintageMode(int vintage_mode); + int getVintageMode(void); + + int setFocusMode(int focus_mode); + int getFocusMode(void); + + int setFaceDetect(int face_detect); + int getFaceDetect(void); + + int setGPSLatitude(const char * gps_latitude); + int setGPSLongitude(const char * gps_longitude); + int setGPSAltitude(const char * gps_altitude); + int setGPSTimeStamp(const char * gps_timestamp); + int cancelAutofocus(void); + int setAEAWBLockUnlock(int ae_lockunlock, int awb_lockunlock); + int setFaceDetectLockUnlock(int facedetect_lockunlock); + int setObjectPosition(int x, int y); + int setObjectTrackingStartStop(int start_stop); + int setTouchAFStartStop(int start_stop); + int setCAFStatus(int on_off); + int getAutoFocusResult(void); + int setAntiBanding(int anti_banding); + int getPostview(void); + int setRecordingSize(int width, int height); + int setGamma(int gamma); + int setSlowAE(int slow_ae); + int setExifOrientationInfo(int orientationInfo); + int setBatchReflection(void); + int setSnapshotCmd(void); + int setCameraSensorReset(void); //s1_camera [ Defense process by ESD input ] + int setSensorMode(int sensor_mode); /* Camcorder fix fps */ + int setShotMode(int shot_mode); /* Shot mode */ + /*VT call*/ + int setVTmode(int vtmode); + int getVTmode(void); + int setBlur(int blur_level); + int getBlur(void); + int setDataLineCheck(int chk_dataline); + int getDataLineCheck(void); + int setDataLineCheckStop(void); + int setDefultIMEI(int imei); + int getDefultIMEI(void); +#endif + + void setFrameRate(int frame_rate); +// void setJpegQuality(int quality); + unsigned char* getJpeg(int*, unsigned int*); + unsigned char* getSnapshotAndJpeg(void); + //[zzangdol] add function + int getExif(unsigned char *pExifDst, unsigned char *pThumbSrc); + +#ifdef JPEG_FROM_SENSOR + void getPostViewConfig(int*, int*, int*); +#endif + +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA + int getPostViewOffset(void); +#endif + int getCameraFd(void); + int getJpegFd(void); + void SetJpgAddr(unsigned char *addr); + unsigned int getPhyAddrY(int); + unsigned int getPhyAddrC(int); +#ifdef SEND_YUV_RECORD_DATA + void getYUVBuffers(unsigned char** virYAddr, unsigned char** virCaddr, int index); +#endif + void pausePreview(); + int initCamera(); + void DeinitCamera(); + +private: + int m_flag_init; + + int m_camera_id; + + int m_cam_fd; + + int m_cam_fd_temp; + int m_cam_fd2_temp; +#ifdef DUAL_PORT_RECORDING + int m_cam_fd2; + struct pollfd m_events_c2; + int m_flag_record_start; + struct fimc_buffer m_buffers_c2[MAX_BUFFERS]; +#endif + + int m_preview_v4lformat; + int m_preview_width; + int m_preview_height; + int m_preview_max_width; + int m_preview_max_height; + + int m_snapshot_v4lformat; + int m_snapshot_width; + int m_snapshot_height; + int m_snapshot_max_width; + int m_snapshot_max_height; + + int m_angle; + int m_fps; + int m_autofocus; + int m_white_balance; + int m_brightness; + int m_image_effect; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + int m_anti_banding; + int m_scene_mode; + int m_flash_mode; +// int m_iso; + int m_metering; + int m_contrast; + int m_saturation; + int m_sharpness; + int m_wdr; + int m_anti_shake; +// int m_jpeg_quality; + int m_zoom_level; + int m_object_tracking; + int m_smart_auto; + int m_beauty_shot; + int m_vintage_mode; +// int m_focus_mode; + int m_face_detect; + int m_object_tracking_start_stop; + int m_recording_width; + int m_recording_height; + long m_gps_latitude; + long m_gps_longitude; + long m_gps_altitude; + long m_gps_timestamp; + int m_vtmode; + int m_sensor_mode; /*Camcorder fix fps */ + int m_shot_mode; /* Shot mode */ + int m_exif_orientation; + int m_blur_level; + int m_chk_dataline; + int m_video_gamma; + int m_slow_ae; + int m_caf_on_off; + int m_default_imei; + int m_camera_af_flag; +#endif + + int m_flag_camera_start; + + int m_jpeg_fd; + int m_jpeg_thumbnail_width; + int m_jpeg_thumbnail_height; + int m_jpeg_quality; + + int m_postview_offset; + + exif_attribute_t mExifInfo; + + struct fimc_buffer m_buffers_c[MAX_BUFFERS]; + struct pollfd m_events_c; + + inline int m_frameSize(int format, int width, int height); + + void setExifChangedAttribute(); + void setExifFixedAttribute(); + void resetCamera(); +}; + +extern unsigned long measure_time(struct timeval *start, struct timeval *stop); + +}; // namespace android + +#endif // ANDROID_HARDWARE_CAMERA_SEC_H diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp new file mode 100644 index 0000000..5c2dc76 --- /dev/null +++ b/libcamera/SecCameraHWInterface.cpp @@ -0,0 +1,2370 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** Copyright@ 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 on 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. +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "CameraHardwareSec" +#include <utils/Log.h> + +#include "SecCameraHWInterface.h" +#include <utils/threads.h> +#include <fcntl.h> +#include <sys/mman.h> + +#ifdef SEND_YUV_RECORD_DATA +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) +#define RECORD_HEAP_SIZE (ALIGN_TO_8KB(ALIGN_TO_128B(1280) * ALIGN_TO_32B(720)) + ALIGN_TO_8KB(ALIGN_TO_128B(1280) * ALIGN_TO_32B(720/2))) +#endif + +namespace android { + +struct ADDRS +{ + unsigned int addr_y; + unsigned int addr_cbcr; +}; + +struct ADDRS_CAP +{ + unsigned int addr_y; + unsigned int width; + unsigned int height; +}; + +CameraHardwareSec::CameraHardwareSec() + : mParameters(), + mPreviewHeap(0), + mRawHeap(0), + mRecordHeap(0), + mJpegHeap(0), + mSecCamera(NULL), + mPreviewRunning(false), + mPreviewFrameSize(0), + mRawFrameSize(0), + mPreviewFrameRateMicrosec(33000), + mNotifyCb(0), + mDataCb(0), + mDataCbTimestamp(0), + mCallbackCookie(0), + mMsgEnabled(0), + mCurrentPreviewFrame(0), + mRecordRunning(false) +#ifdef JPEG_FROM_SENSOR + , + mPostViewWidth(0), + mPostViewHeight(0), + mPostViewSize(0) +#endif + #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + , + mObjectTrackingStatus(0), + mSmartautosceneRunning(false), + mSmartautoscene_current_status(0), + mSmartautoscene_previous_status(0) + #endif +{ + LOGV("%s()", __FUNCTION__); + int ret = 0; + mNoHwHandle = 0; + + mSecCamera = SecCamera::createInstance(); + if(mSecCamera == NULL) + { + LOGE("ERR(%s):Fail on mSecCamera object creation", __FUNCTION__); + } + + ret = mSecCamera->initCamera(); + if(ret < 0) + { + LOGE("ERR(%s):Fail on mSecCamera init", __FUNCTION__); + } + + if(mSecCamera->flagCreate() == 0) + { + LOGE("ERR(%s):Fail on mSecCamera->flagCreate()", __FUNCTION__); + } + +#ifndef PREVIEW_USING_MMAP + int previewHeapSize = sizeof(struct ADDRS) * kBufferCount; + LOGV("mPreviewHeap : MemoryHeapBase(previewHeapSize(%d))", previewHeapSize); + mPreviewHeap = new MemoryHeapBase(previewHeapSize); + if (mPreviewHeap->getHeapID() < 0) + { + LOGE("ERR(%s): Preview heap creation fail", __func__); + mPreviewHeap.clear(); + } +#endif + +#ifdef SEND_YUV_RECORD_DATA + int recordHeapSize = RECORD_HEAP_SIZE; +#else + int recordHeapSize = sizeof(struct ADDRS) * kBufferCount; +#endif + LOGV("mRecordHeap : MemoryHeapBase(recordHeapSize(%d))", recordHeapSize); + mRecordHeap = new MemoryHeapBase(recordHeapSize); + if (mRecordHeap->getHeapID() < 0) + { + LOGE("ERR(%s): Record heap creation fail", __func__); + mRecordHeap.clear(); + } + +#ifdef JPEG_FROM_SENSOR + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + LOGV("mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",mPostViewWidth,mPostViewHeight,mPostViewSize); +#endif + +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA + int rawHeapSize = mPostViewSize; +#else + int rawHeapSize = sizeof(struct ADDRS_CAP); +#endif + LOGV("mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize); + mRawHeap = new MemoryHeapBase(rawHeapSize); + if (mRawHeap->getHeapID() < 0) + { + LOGE("ERR(%s): Raw heap creation fail", __func__); + mRawHeap.clear(); + } + + initDefaultParameters(); +} + +void CameraHardwareSec::initDefaultParameters() +{ + if(mSecCamera == NULL) + { + LOGE("ERR(%s):mSecCamera object is NULL", __FUNCTION__); + return; + } + + CameraParameters p; + + int preview_max_width = 0; + int preview_max_height = 0; + int snapshot_max_width = 0; + int snapshot_max_height = 0; + + int camera_id = 1; + + p.set("camera-id", camera_id); + + if(camera_id == 1) + mSecCamera->setCameraId(SecCamera::CAMERA_ID_BACK); + else + mSecCamera->setCameraId(SecCamera::CAMERA_ID_FRONT); + + if(mSecCamera->getPreviewMaxSize(&preview_max_width, &preview_max_height) < 0) + { + LOGE("getPreviewMaxSize fail (%d / %d) \n", preview_max_width, preview_max_height); + preview_max_width = LCD_WIDTH; + preview_max_height = LCD_HEIGHT; + } + if(mSecCamera->getSnapshotMaxSize(&snapshot_max_width, &snapshot_max_height) < 0) + { + LOGE("getSnapshotMaxSize fail (%d / %d) \n", snapshot_max_width, snapshot_max_height); + snapshot_max_width = LCD_WIDTH; + snapshot_max_height = LCD_HEIGHT; + } + +#ifdef PREVIEW_USING_MMAP + p.setPreviewFormat("yuv420sp"); +#else + p.setPreviewFormat("yuv420sp_custom"); +#endif + p.setPreviewSize(preview_max_width, preview_max_height); + p.setPreviewFrameRate(30); + + p.setPictureFormat("jpeg"); + p.setPictureSize(snapshot_max_width, snapshot_max_height); + p.set("jpeg-quality", "100"); // maximum quality +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + p.set("preview-size-values","640x480,800x480"); //s1_camera [ 3-party application ¿¡¼ get supported preview size ¾ÈµÇ´Â Çö»ó ¼öÁ¤ ] + p.set("picture-size-values","2560x1920,2048x1536,1600x1200,640x480,2560x1536,2048x1232,1600x960,800x480"); + p.set("preview-format-values", "yuv420sp"); + p.set("preview-frame-rate-values", "15,30"); + p.set("picture-format-values", "jpeg"); + p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "160x120,0x0"); + p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, CameraParameters::PIXEL_FORMAT_YUV420SP); + p.set("focus-mode-values", "auto,macro"); + p.set("antibanding-values", "auto,50hz,60hz,off"); + p.set("effect-values", "none,mono,negative,sepia"); + p.set("flash-mode-values", "off"); +// p.set("focus-mode-values", "auto,infinity,macro"); + p.set("scene-mode-values", "auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight"); + p.set("whitebalance-values", "auto,incandescent,fluorescent,daylight,cloudy-daylight"); +//add the max and min for adjust value[20100728 giung.jung] + p.set("sharpness-min", 0); + p.set("sharpness-max", 4); + p.set("saturation-min", 0); + p.set("saturation-max", 4); + p.set("contrast-min", 0); + p.set("contrast-max", 4); + +#else + // List supported picture size values //Kamat + p.set("picture-size-values", "2560x1920,2048x1536,1600x1200,1280x960"); +#endif + // These values must be multiples of 16, so we can't do 427x320, which is the exact size on + // screen we want to display at. 480x360 doesn't work either since it's a multiple of 8. + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "160"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "120"); + p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "100"); + + p.set("rotation", 0); + p.set("whitebalance", "auto"); +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + p.set("effect", "none"); + p.set("scene-mode", "auto"); + p.set("vintagemode", "off"); + p.set("sharpness", 2); + p.set("contrast", 2); + p.set("saturation", 2); + p.set("iso", "auto"); + p.set("metering", "center"); + //p.set("facedetect", 0); + p.set("flash-mode", "off"); + p.set("focus-mode", "auto"); + p.set("anti-shake", 0); + p.set("wdr", 0); + p.set("smart-auto",0); + p.set("beauty-shot", 0); + p.set("antibanding", "auto"); + p.set("video_recording_gamma", "off"); + p.set("slow_ae", "off"); + p.set("vtmode", 0); + p.set("chk_dataline", 0); + p.set("blur", 0); +#else + p.set("image-effects", "original"); +#endif + + p.set(CameraParameters::KEY_ZOOM, "0"); + p.set(CameraParameters::KEY_ZOOM_SUPPORTED, "true"); + p.set(CameraParameters::KEY_MAX_ZOOM, "12"); + p.set(CameraParameters::KEY_ZOOM_RATIOS, "100,125,150,175,200,225,250,275,300,324,350,375,400"); + + p.set(CameraParameters::KEY_FOCAL_LENGTH, "3.79"); + + p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "51.2"); + p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "39.4"); + + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); + p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "4"); + p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-4"); + p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5"); + + p.set("AppShutterSound", 0); + if (setParameters(p) != NO_ERROR) + { + LOGE("ERR(%s):Fail on setParameters(p)", __FUNCTION__); + } +} + +CameraHardwareSec::~CameraHardwareSec() +{ + LOGV("%s()", __FUNCTION__); + + mSecCamera->DeinitCamera(); + + if(mRawHeap != NULL) + mRawHeap.clear(); + + if(mJpegHeap != NULL) + mJpegHeap.clear(); + + if(mPreviewHeap != NULL) + mPreviewHeap.clear(); + + if(mRecordHeap != NULL) + mRecordHeap.clear(); + + mSecCamera = NULL; + + singleton.clear(); +} + +sp<IMemoryHeap> CameraHardwareSec::getPreviewHeap() const +{ + return mPreviewHeap; +} + +sp<IMemoryHeap> CameraHardwareSec::getRawHeap() const +{ + return mRawHeap; +} + +//Kamat added: New code as per eclair framework +void CameraHardwareSec::setCallbacks(notify_callback notify_cb, + data_callback data_cb, + data_callback_timestamp data_cb_timestamp, + void* user) +{ + Mutex::Autolock lock(mLock); + mNotifyCb = notify_cb; + mDataCb = data_cb; + mDataCbTimestamp = data_cb_timestamp; + mCallbackCookie = user; +} + +void CameraHardwareSec::enableMsgType(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + mMsgEnabled |= msgType; +} + +void CameraHardwareSec::disableMsgType(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + mMsgEnabled &= ~msgType; +} + +bool CameraHardwareSec::msgTypeEnabled(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + return (mMsgEnabled & msgType); +} + +// --------------------------------------------------------------------------- + +int CameraHardwareSec::previewThread() +{ + int index; + + index = mSecCamera->getPreview(); + if(index < 0) + { + LOGE("ERR(%s):Fail on SecCamera->getPreview()", __FUNCTION__); + return UNKNOWN_ERROR; + } + + nsecs_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC); + +#ifdef PREVIEW_USING_MMAP + int width, height, frame_size, offset; + mSecCamera->getPreviewSize(&width, &height, &frame_size); + + offset = (frame_size+8)*index; + sp<MemoryBase> buffer = new MemoryBase(mPreviewHeap, offset, frame_size); + + unsigned int phyYAddr = mSecCamera->getPhyAddrY(index); + unsigned int phyCAddr = mSecCamera->getPhyAddrC(index); + if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) + { + LOGE("ERR(%s):Fail on SecCamera. Invalid PhyAddr, Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + return UNKNOWN_ERROR; + } + memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset+frame_size ), &phyYAddr, 4); + memcpy(static_cast<unsigned char *>(mPreviewHeap->base()) + (offset+frame_size+4), &phyCAddr, 4); +#else + unsigned int phyYAddr = mSecCamera->getPhyAddrY(index); + unsigned int phyCAddr = mSecCamera->getPhyAddrC(index); + if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) + { + LOGE("ERR(%s):Fail on SecCamera getPhyAddr Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + return UNKNOWN_ERROR; + } + struct ADDRS *addrs = (struct ADDRS *)mPreviewHeap->base(); + + sp<MemoryBase> buffer = new MemoryBase(mPreviewHeap, index * sizeof(struct ADDRS), sizeof(struct ADDRS)); + addrs[index].addr_y = phyYAddr; + addrs[index].addr_cbcr = phyCAddr; +#endif //PREVIEW_USING_MMAP + + // Notify the client of a new frame. //Kamat --eclair + if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) + { + mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie); + } +// LOG_CAMERA_PREVIEW("previewThread: addr_y(0x%08X) addr_cbcr(0x%08X)", addrs[index].addr_y, addrs[index].addr_cbcr); + + if(mRecordRunning == true) + { +#ifdef SEND_YUV_RECORD_DATA + int width, height, frame_size; + unsigned char* virYAddr; + unsigned char* virCAddr; + mSecCamera->getPreviewSize(&width, &height, &frame_size); + mSecCamera->getYUVBuffers(&virYAddr, &virCAddr, index); + sp<MemoryBase> buffer = new MemoryBase(mRecordHeap, 0, frame_size); + //memcpy(mRecordHeap->base(), (void*)virYAddr, width*height); + //memcpy(mRecordHeap->base()+(width*height),(void*)virCAddr, width*height*0.5); + memcpy(mRecordHeap->base(), (void*)virYAddr, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + memcpy(mRecordHeap->base() + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)),(void*)virCAddr, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height/2))); +#else +#ifdef DUAL_PORT_RECORDING + int index = mSecCamera->getRecord(); + if(index < 0) + { + LOGE("ERR(%s):Fail on SecCamera->getRecord()", __FUNCTION__); + return UNKNOWN_ERROR; + } + unsigned int phyYAddr = mSecCamera->getRecPhyAddrY(index); + unsigned int phyCAddr = mSecCamera->getRecPhyAddrC(index); + if(phyYAddr == 0xffffffff || phyCAddr == 0xffffffff) + { + LOGE("ERR(%s):Fail on SecCamera getRectPhyAddr Y addr = %0x C addr = %0x", __FUNCTION__, phyYAddr, phyCAddr); + return UNKNOWN_ERROR; + } +#endif//DUAL_PORT_RECORDING + struct ADDRS *addrs = (struct ADDRS *)mRecordHeap->base(); + + sp<MemoryBase> buffer = new MemoryBase(mRecordHeap, index * sizeof(struct ADDRS), sizeof(struct ADDRS)); + addrs[index].addr_y = phyYAddr; + addrs[index].addr_cbcr = phyCAddr; +#endif + // Notify the client of a new frame. //Kamat --eclair + if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) + { + //nsecs_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC); + mDataCbTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, buffer, mCallbackCookie); + } + } +#ifdef DUAL_PORT_RECORDING + else if(mRecordRunning == false) + { + if(mSecCamera->stopRecord() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->stopRecord()", __FUNCTION__); + return UNKNOWN_ERROR; + } + } +#endif + +// buffer.clear(); + + // Wait for it... + if(mTimeStart.tv_sec == 0 && mTimeStart.tv_usec == 0) + { + gettimeofday(&mTimeStart, NULL); + } else + { + gettimeofday(&mTimeStop, NULL); + long time = measure_time(&mTimeStart, &mTimeStop); + + int delay = (mPreviewFrameRateMicrosec > time) ? mPreviewFrameRateMicrosec - time : 0; + usleep(delay); + //LOG_CAMERA_PREVIEW("delay = %d time = %ld us\n ", delay, time); + gettimeofday(&mTimeStart, NULL); + } + + return NO_ERROR; +} + +status_t CameraHardwareSec::startPreview() +{ + int ret = 0; //s1 [Apply factory standard] + + LOGE("%s()", __FUNCTION__); + + Mutex::Autolock lock(mLock); + if (mPreviewThread != 0) { + // already running + return INVALID_OPERATION; + } + + memset(&mTimeStart, 0, sizeof(mTimeStart)); + memset(&mTimeStop, 0, sizeof(mTimeStop)); + + mSecCamera->stopPreview(); + +#if 1 //s1 [Apply factory standard] + ret = mSecCamera->startPreview(); + LOGE("%s : return startPreview %d", __FUNCTION__, ret); + + if(ret < 0) +#else + if(mSecCamera->startPreview() < 0) +#endif + { + LOGE("ERR(%s):Fail on mSecCamera->startPreview()", __FUNCTION__); + if (mMsgEnabled & CAMERA_MSG_ERROR) + { + mNotifyCb(CAMERA_MSG_ERROR, -2, 0, mCallbackCookie); + } + return -1; //UNKNOWN_ERROR; + } + +#ifdef PREVIEW_USING_MMAP + if(mPreviewHeap != NULL) + mPreviewHeap.clear(); + int width, height, frame_size; + mSecCamera->getPreviewSize(&width, &height, &frame_size); + int previewHeapSize = (frame_size+8) * kBufferCount; + LOGD("MemoryHeapBase(fd(%d), size(%d), width(%d), height(%d))", (int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), width, height); + mPreviewHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(previewHeapSize), (uint32_t)0); +#endif + +#ifdef JPEG_FROM_SENSOR + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + LOGE("CameraHardwareSec: mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",mPostViewWidth,mPostViewHeight,mPostViewSize); +#endif + +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA + int rawHeapSize = mPostViewSize; +#else + int rawHeapSize = sizeof(struct ADDRS_CAP); +#endif + LOGE("CameraHardwareSec: mRawHeap : MemoryHeapBase(previewHeapSize(%d))", rawHeapSize); + mRawHeap = new MemoryHeapBase(rawHeapSize); + if (mRawHeap->getHeapID() < 0) + { + LOGE("ERR(%s): Raw heap creation fail", __func__); + mRawHeap.clear(); + } + +#if 0 + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + struct ADDRS_CAP *addrs = (struct ADDRS_CAP *)mRawHeap->base(); + + LOGE("[5B 1] mPostViewWidth = %d mPostViewHeight = %d mPostViewSize = %d",mPostViewWidth,mPostViewHeight); + + addrs[0].width = mPostViewWidth; + addrs[0].height = mPostViewHeight; + +#endif + + mPreviewRunning = true; + mPreviewThread = new PreviewThread(this); + return NO_ERROR; +} + +void CameraHardwareSec::stopPreview() +{ + LOGV("%s()", __FUNCTION__); + + sp<PreviewThread> previewThread; + + { // scope for the lock + Mutex::Autolock lock(mLock); + previewThread = mPreviewThread; + } + + // don't hold the lock while waiting for the thread to quit +// if (previewThread != 0) { +// previewThread->requestExitAndWait(); +// } + + Mutex::Autolock lock(mLock); + mPreviewThread.clear(); + + if(!mNoHwHandle) + if(mSecCamera->stopPreview() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->stopPreview()", __FUNCTION__); + } + + mPreviewRunning = false; +} + +bool CameraHardwareSec::previewEnabled() { + LOGV("%s() : %d", __FUNCTION__, mPreviewThread != 0); + return mPreviewThread != 0; +} + +// --------------------------------------------------------------------------- + +status_t CameraHardwareSec::startRecording() +{ + LOGV("%s()", __FUNCTION__); + +#ifdef DUAL_PORT_RECORDING + if(mSecCamera->startRecord() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->startRecord()", __FUNCTION__); + return UNKNOWN_ERROR; + } +#endif + + mRecordRunning = true; + return NO_ERROR; +} + +void CameraHardwareSec::stopRecording() +{ + LOGV("%s()", __FUNCTION__); + + mRecordRunning = false; +} + +bool CameraHardwareSec::recordingEnabled() +{ + LOGV("%s()", __FUNCTION__); + + return mRecordRunning; +} + +void CameraHardwareSec::releaseRecordingFrame(const sp<IMemory>& mem) +{ + LOG_CAMERA_PREVIEW("%s()", __FUNCTION__); + +// ssize_t offset; size_t size; +// sp<MemoryBase> mem1 = mem; +// sp<MemoryHeapBase> heap = mem->getMemory(&offset, &size); +// sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + +// mem1.clear(); +// heap.clear(); +} + +// --------------------------------------------------------------------------- + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +int CameraHardwareSec::smartautosceneThread() +{ + + mSmartautoscene_current_status = mSecCamera->getAutosceneStatus(); + + if(mSmartautoscene_current_status < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->getAutosceneStatus()", __FUNCTION__); + return UNKNOWN_ERROR; + } + + if(mSmartautoscene_current_status != mSmartautoscene_previous_status) + { + //if (mMsgEnabled & CAMERA_MSG_SMARTAUTO_SCENE_STATUS) + //mNotifyCb(CAMERA_MSG_SMARTAUTO_SCENE_STATUS, mSmartautoscene_current_status, 0, mCallbackCookie); + LOGE("%s CAMERA_MSG_SMARTAUTO_SCENE_STATUS(%d) Callback!!!!!!!! ", __FUNCTION__,mSmartautoscene_current_status); + mSmartautoscene_previous_status = mSmartautoscene_current_status; + } + else + { + LOGE("%s current_status(%d) is same with previous_status(%d)", __FUNCTION__,mSmartautoscene_current_status,mSmartautoscene_previous_status); + } + usleep(2000*1000); //2000ms delay + LOGE("DELAY(2000ms)!!!!!!!"); + return NO_ERROR; +} + +status_t CameraHardwareSec::startSmartautoscene() +{ + LOGV("%s()", __FUNCTION__); + +// Mutex::Autolock lock(mLock); + + if (mSmartautosceneThread != 0) { + // already running + return INVALID_OPERATION; + } + + mSmartautosceneRunning = true; + mSmartautosceneThread = new SmartautosceneThread(this); + return NO_ERROR; +} + +void CameraHardwareSec::stopSmartautoscene() +{ + LOGV("%s()", __FUNCTION__); + + sp<SmartautosceneThread> smartautosceneThread; + + { // scope for the lock +// Mutex::Autolock lock(mLock); + smartautosceneThread = mSmartautosceneThread; + } + + // don't hold the lock while waiting for the thread to quit + if (smartautosceneThread != 0) { + smartautosceneThread->requestExitAndWait(); + } + +// Mutex::Autolock lock(mLock); + mSmartautosceneThread.clear(); + + mSmartautosceneRunning = false; +} + +bool CameraHardwareSec::smartautosceneEnabled() { + LOGV("%s() : %d", __FUNCTION__, mSmartautosceneThread != 0); + return mSmartautosceneThread != 0; +} + +#endif + + +int CameraHardwareSec::beginAutoFocusThread(void *cookie) +{ + LOGV("%s()", __FUNCTION__); + CameraHardwareSec *c = (CameraHardwareSec *)cookie; + return c->autoFocusThread(); +} + +int CameraHardwareSec::autoFocusThread() +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + int count =0; + int af_status =0 ; +#endif + + LOGV("%s()", __FUNCTION__); +// usleep(50000); // 1frame delay 50ms + if(mSecCamera->setAutofocus() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setAutofocus()", __FUNCTION__); + return UNKNOWN_ERROR; + } + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +// usleep(10000); + af_status = mSecCamera->getAutoFocusResult(); + + if (af_status == 0x01) + { + LOGV("%s() AF Success!!", __FUNCTION__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + } + else if (af_status == 0x02) + { + LOGV("%s() AF Cancelled !!", __FUNCTION__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, 0x02, 0, mCallbackCookie); + } + else + { + LOGV("%s() AF Fail !!", __FUNCTION__); + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); + } +#else + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); +#endif + return NO_ERROR; +} + +status_t CameraHardwareSec::autoFocus() +{ + LOGV("%s()", __FUNCTION__); + Mutex::Autolock lock(mLock); + if (createThread(beginAutoFocusThread, this) == false) + return UNKNOWN_ERROR; + return NO_ERROR; +} + +/* 2009.10.14 by icarus for added interface */ +status_t CameraHardwareSec::cancelAutoFocus() +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGV("%s()", __FUNCTION__); + + if(mSecCamera->cancelAutofocus() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->cancelAutofocus()", __FUNCTION__); + return UNKNOWN_ERROR; + } +#endif + return NO_ERROR; +} + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION +status_t CameraHardwareSec::objectTracking(int onoff) +{ + LOGV("%s() onoff = %d", __FUNCTION__, onoff); + + Mutex::Autolock lock(mLock); + if(onoff) + { + if (mObjectTrackingThread == 0) { + mObjectTrackingThread = new ObjectTrackingThread(this); + } + mObjectTrackingRunning=true; + } + else + { + if (mObjectTrackingThread != 0) { + mObjectTrackingThread->requestExitAndWait(); + } + mObjectTrackingThread.clear(); + mObjectTrackingRunning=false; + } + return 0; +} + +int CameraHardwareSec::save_jpeg( unsigned char * real_jpeg, int jpeg_size) +{ + FILE *yuv_fp = NULL; + char filename[100], *buffer = NULL; + + /* file create/open, note to "wb" */ + yuv_fp = fopen("/data/camera_dump.jpeg", "wb"); + if (yuv_fp==NULL) + { + LOGE("Save jpeg file open error"); + return -1; + } + + LOGE("[BestIQ] real_jpeg size ========> %d\n", jpeg_size); + buffer = (char *) malloc(jpeg_size); + if(buffer == NULL) + { + LOGE("Save YUV] buffer alloc failed"); + if(yuv_fp) fclose(yuv_fp); + return -1; + } + + memcpy(buffer, real_jpeg, jpeg_size); + + fflush(stdout); + + fwrite(buffer, 1, jpeg_size, yuv_fp); + + fflush(yuv_fp); + + if(yuv_fp) + fclose(yuv_fp); + if(buffer) + free(buffer); + + return 0; +} + + +int CameraHardwareSec::objectTrackingThread() +{ + int new_obj_status; + new_obj_status = mSecCamera->getObjectTrackingStatus(); +#if 0 //temp till define callback msg + if (mObjectTrackingStatus != new_obj_status) + { + mObjectTrackingStatus = new_obj_status; + if (mMsgEnabled & CAMERA_MSG_OBJ_TRACKING) + mNotifyCb(CAMERA_MSG_OBJ_TRACKING, new_obj_status, 0, mCallbackCookie); + } +#endif + usleep(100000); //100ms + return NO_ERROR; +} +#endif +/*static*/ int CameraHardwareSec::beginPictureThread(void *cookie) +{ + LOGV("%s()", __FUNCTION__); + CameraHardwareSec *c = (CameraHardwareSec *)cookie; + return c->pictureThread(); +} + +void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t size) +{ + int nw, cnt = 0; + uint32_t written = 0; + + LOGD("opening file [%s]\n", fname); + int fd = open(fname, O_RDWR | O_CREAT); + if (fd < 0) { + LOGE("failed to create file [%s]: %s", fname, strerror(errno)); + return; + } + + LOGD("writing %d bytes to file [%s]\n", size, fname); + while (written < size) { + nw = ::write(fd, + buf + written, + size - written); + if (nw < 0) { + LOGE("failed to write to file %d [%s]: %s",written,fname, strerror(errno)); + break; + } + written += nw; + cnt++; + } + LOGD("done writing %d bytes to file [%s] in %d passes\n",size, fname, cnt); + ::close(fd); +} + +int CameraHardwareSec::pictureThread() +{ + LOGV("%s()", __FUNCTION__); + + int jpeg_size = 0; + int ret = NO_ERROR; + unsigned char * jpeg_data = NULL; + int postview_offset = 0; + unsigned char * postview_data = NULL; + + //unsigned int addr; + unsigned char * addr = NULL; + int mPostViewWidth, mPostViewHeight, mPostViewSize; + int cap_width, cap_height, cap_frame_size; + + mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); + int postviewHeapSize = mPostViewWidth*mPostViewHeight*2; //*size = (BACK_CAMERA_POSTVIEW_WIDTH * BACK_CAMERA_POSTVIEW_HEIGHT * BACK_CAMERA_POSTVIEW_BPP)/8; + mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); + LOGE("[kidggang]:func(%s):line(%d)&cap_width(%d), &cap_height(%d), &cap_frame_size(%d)\n",__FUNCTION__,__LINE__,cap_width, cap_height, cap_frame_size); + +// sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, postviewHeapSize); + + LOG_TIME_DEFINE(0) + LOG_TIME_START(0) +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA + sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, mPostViewSize+8); +#else + sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, sizeof(struct ADDRS_CAP)); +#endif + + struct ADDRS_CAP *addrs = (struct ADDRS_CAP *)mRawHeap->base(); + +#ifdef JPEG_FROM_SENSOR + addrs[0].width = mPostViewWidth; + addrs[0].height = mPostViewHeight; + LOGV("[5B] mPostViewWidth = %d mPostViewHeight = %d\n",mPostViewWidth,mPostViewHeight); +#else + mParameters.getPictureSize((int*)&addrs[0].width, (int*)&addrs[0].height); +#endif + + + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) { //[zzangdol] CAMERA_ID_BACK +#ifndef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + { + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + } +#endif + }//[zzangdol]CAMERA_ID_BACK + + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) + { + LOG_TIME_DEFINE(1) + LOG_TIME_START(1) + + int picture_size, picture_width, picture_height; + mSecCamera->getSnapshotSize(&picture_width, &picture_height, &picture_size); + int picture_format = mSecCamera->getSnapshotPixelFormat(); + + unsigned int phyAddr; +#ifdef JPEG_FROM_SENSOR + // Modified the shutter sound timing for Jpeg capture + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) + mSecCamera->setSnapshotCmd(); +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + { + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); + } +#endif + + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){ //[zzangdol] CAMERA_ID_BACK + jpeg_data = mSecCamera->getJpeg(&jpeg_size, &phyAddr); + if(jpeg_data == NULL) + { + LOGE("ERR(%s):Fail on SecCamera->getSnapshot()", __FUNCTION__); + ret = UNKNOWN_ERROR; + } + }//[zzangdol] CAMERA_ID_BACK + else + { + addr = mSecCamera->getSnapshotAndJpeg(); + //LOGV("[zzangdol] getSnapshotAndJpeg\n"); + } +#else + phyAddr = mSecCamera->getSnapshotAndJpeg(); + jpeg_data = mSecCamera->yuv2Jpeg((unsigned char*)phyAddr, 0, &jpeg_size, picture_width, picture_height, picture_format); +#endif + +#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA + postview_offset = mSecCamera->getPostViewOffset(); + if(jpeg_data != NULL) + memcpy(mRawHeap->base(), jpeg_data+postview_offset, mPostViewSize); +#else + addrs[0].addr_y = phyAddr; +#endif + + LOG_TIME_END(1) + LOG_CAMERA("getSnapshotAndJpeg interval: %lu us", LOG_TIME(1)); + } + + int JpegImageSize, JpegExifSize; + sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBase(mPostViewSize); + sp<MemoryHeapBase> JpegHeap = new MemoryHeapBase(4300000); + decodeInterleaveData(jpeg_data, 4261248, mPostViewWidth, mPostViewHeight, + &JpegImageSize, JpegHeap->base(), PostviewHeap->base()); + + sp<MemoryBase> postview = new MemoryBase(PostviewHeap, 0, postviewHeapSize); + memcpy(mRawHeap->base(),PostviewHeap->base(), postviewHeapSize); +#if 0//def SWP1_CAMERA_ADD_ADVANCED_FUNCTION + if (mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) + { + int postviewHeapSize = mPostViewSize; + sp<MemoryHeapBase> mPostviewHeap = new MemoryHeapBase(postviewHeapSize); + + postview_data = jpeg_data + postview_offset; + sp<MemoryBase> postview = new MemoryBase(mPostviewHeap, 0, postviewHeapSize); + + if(postview_data != NULL) + memcpy(mPostviewHeap->base(), postview_data, postviewHeapSize); + + mDataCb(CAMERA_MSG_POSTVIEW_FRAME, postview, mCallbackCookie); + } +#endif //#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + + if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) + { + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK){ + sp<MemoryHeapBase> ExifHeap = new MemoryHeapBase(EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE); + JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->base(), + (unsigned char *)PostviewHeap->base()); + + LOGE("JpegExifSize=%d", JpegExifSize); + unsigned char *ExifStart = (unsigned char *)JpegHeap->base() + 2; + unsigned char *ImageStart = ExifStart + JpegExifSize; + + memmove(ImageStart, ExifStart, JpegImageSize - 2); + memcpy(ExifStart, ExifHeap->base(), JpegExifSize); + sp<MemoryBase> mem = new MemoryBase(JpegHeap, 0, JpegImageSize + JpegExifSize); + + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie); + + mDataCb(CAMERA_MSG_RAW_IMAGE, buffer, mCallbackCookie); + }//[zzangdol] CAMERA_ID_BACK + else + { + LOGV("[zzangdol] COMPRESSED_IMAGE\n"); + //mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); + //sp<MemoryHeapBase> mHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(cap_frame_size * kBufferCount), (uint32_t)0); + sp<MemoryHeapBase> mHeap = new MemoryHeapBase(2000000); + memcpy(mHeap->base(), addr, cap_frame_size); + sp<MemoryBase> mem = new MemoryBase(mHeap , 0, cap_frame_size); + //save_postview("/data/front.yuv", (uint8_t *)mHeap->base(), yuv_frame_size2); + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);//[zzangdol] + } + } + + LOG_TIME_END(0) + LOG_CAMERA("pictureThread interval: %lu us", LOG_TIME(0)); + + return ret; +} + +status_t CameraHardwareSec::takePicture() +{ + LOGV("%s()", __FUNCTION__); + + stopPreview(); + mNoHwHandle = 0; + + if (createThread(beginPictureThread, this) == false) + return -1; + + return NO_ERROR; +} + +status_t CameraHardwareSec::cancelPicture() +{ + return NO_ERROR; +} + +int CameraHardwareSec::decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData) +{ + if (pInterleaveData == NULL) + return false; + + bool ret = true; + unsigned int *interleave_ptr = (unsigned int *)pInterleaveData; + unsigned char *jpeg_ptr = (unsigned char *)pJpegData; + unsigned char *yuv_ptr = (unsigned char *)pYuvData; + unsigned char *p; + int jpeg_size = 0; + int yuv_size = 0; + + int i = 0; + + LOGE("decodeInterleaveData Start~~~"); + while(i < interleaveDataSize) { + if ((*interleave_ptr == 0xFFFFFFFF) || + (*interleave_ptr == 0x02FFFFFF) || + (*interleave_ptr == 0xFF02FFFF)) { + // Padding Data +// LOGE("%d(%x) padding data\n", i, *interleave_ptr); + interleave_ptr++; + i += 4; + } + else if ((*interleave_ptr & 0xFFFF) == 0x05FF) { + // Start-code of YUV Data +// LOGE("%d(%x) yuv data\n", i, *interleave_ptr); + p = (unsigned char *)interleave_ptr; + p += 2; + i += 2; + + // Extract YUV Data + if (pYuvData != NULL) { + memcpy(yuv_ptr, p, yuvWidth * 2); + yuv_ptr += yuvWidth * 2; + yuv_size += yuvWidth * 2; + } + p += yuvWidth * 2; + i += yuvWidth * 2; + + // Check End-code of YUV Data + if ((*p == 0xFF) && (*(p + 1) == 0x06)) { + interleave_ptr = (unsigned int *)(p + 2); + i += 2; + } else { + ret = false; + break; + } + + } + else { + // Extract JPEG Data +// LOGE("%d(%x) jpg data, jpeg_size = %d bytes\n", i, *interleave_ptr, jpeg_size); + if (pJpegData != NULL) { + memcpy(jpeg_ptr, interleave_ptr, 4); + jpeg_ptr += 4; + jpeg_size += 4; + } + interleave_ptr++; + i += 4; + } + } + if (ret) { + if (pJpegData != NULL) { + // Remove Padding after EOI + for (i=0; i<3; i++) { + if (*(--jpeg_ptr) != 0xFF) { + break; + } + jpeg_size--; + } + *pJpegSize = jpeg_size; + + } + // Check YUV Data Size + if (pYuvData != NULL) { + if (yuv_size != (yuvWidth * yuvHeight * 2)) { + ret = false; + } + } + } + LOGE("decodeInterleaveData End~~~"); + return ret; +} + +status_t CameraHardwareSec::dump(int fd, const Vector<String16>& args) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + AutoMutex lock(&mLock); + if (mSecCamera != 0) { + mSecCamera->dump(fd, args); + mParameters.dump(fd, args); + snprintf(buffer, 255, " preview frame(%d), size (%d), running(%s)\n", mCurrentPreviewFrame, mPreviewFrameSize, mPreviewRunning?"true": "false"); + result.append(buffer); + } else { + result.append("No camera client yet.\n"); + } + write(fd, result.string(), result.size()); + return NO_ERROR; +} + +status_t CameraHardwareSec::setParameters(const CameraParameters& params) +{ + LOGV("%s()", __FUNCTION__); + + Mutex::Autolock lock(mLock); + + status_t ret = NO_ERROR; + + mParameters = params; + + // set camera id + int new_camera_id = params.getInt("camera-id"); + if(0 <= new_camera_id) + { + if(mSecCamera->setCameraId(new_camera_id) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setCameraId(camera_id(%d))", __FUNCTION__, new_camera_id); + ret = UNKNOWN_ERROR; + } + } + + // preview size + int new_preview_width = 0; + int new_preview_height = 0; + params.getPreviewSize(&new_preview_width, &new_preview_height); + const char * new_str_preview_format = params.getPreviewFormat(); + if(0 < new_preview_width && 0 < new_preview_height && new_str_preview_format != NULL) + { + int new_preview_format = 0; + + if (strcmp(new_str_preview_format, "rgb565") == 0) + new_preview_format = V4L2_PIX_FMT_RGB565; + else if (strcmp(new_str_preview_format, "yuv420sp") == 0) + new_preview_format = V4L2_PIX_FMT_NV21; //Kamat + else if (strcmp(new_str_preview_format, "yuv420sp_custom") == 0) + new_preview_format = V4L2_PIX_FMT_NV12T; //Kamat + else if (strcmp(new_str_preview_format, "yuv420p") == 0) + new_preview_format = V4L2_PIX_FMT_YUV420; + else if (strcmp(new_str_preview_format, "yuv422i") == 0) + new_preview_format = V4L2_PIX_FMT_YUYV; + else if (strcmp(new_str_preview_format, "yuv422p") == 0) + new_preview_format = V4L2_PIX_FMT_YUV422P; + else + new_preview_format = V4L2_PIX_FMT_NV21; //for 3rd party + + if(mSecCamera->setPreviewSize(new_preview_width, new_preview_height, new_preview_format) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setPreviewSize(width(%d), height(%d), format(%d))", __FUNCTION__, new_preview_width, new_preview_height, new_preview_format); + ret = UNKNOWN_ERROR; + } + } + + int new_picture_width = 0; + int new_picture_height = 0; + params.getPictureSize(&new_picture_width, &new_picture_height); + if(0 < new_picture_width && 0 < new_picture_height) + { + if(mSecCamera->setSnapshotSize(new_picture_width, new_picture_height) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotSize(width(%d), height(%d))", __FUNCTION__, new_picture_width, new_picture_height); + ret = UNKNOWN_ERROR; + } + } + + // picture format + const char * new_str_picture_format = params.getPictureFormat(); + if(new_str_picture_format != NULL) + { + int new_picture_format = 0; + + if (strcmp(new_str_picture_format, "rgb565") == 0) + new_picture_format = V4L2_PIX_FMT_RGB565; + else if (strcmp(new_str_picture_format, "yuv420sp") == 0) + new_picture_format = V4L2_PIX_FMT_NV21; //Kamat: Default format + else if (strcmp(new_str_picture_format, "yuv420sp_custom") == 0) + new_picture_format = V4L2_PIX_FMT_NV12T; + else if (strcmp(new_str_picture_format, "yuv420p") == 0) + new_picture_format = V4L2_PIX_FMT_YUV420; + else if (strcmp(new_str_picture_format, "yuv422i") == 0) + new_picture_format = V4L2_PIX_FMT_YUYV; + else if (strcmp(new_str_picture_format, "uyv422i_custom") == 0) //Zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (strcmp(new_str_picture_format, "uyv422i") == 0) //Non-zero copy UYVY format + new_picture_format = V4L2_PIX_FMT_UYVY; + else if (strcmp(new_str_picture_format, "jpeg") == 0) +#ifdef JPEG_FROM_SENSOR + new_picture_format = V4L2_PIX_FMT_UYVY; +#else + new_picture_format = V4L2_PIX_FMT_YUYV; +#endif + else if (strcmp(new_str_picture_format, "yuv422p") == 0) + new_picture_format = V4L2_PIX_FMT_YUV422P; + else + new_picture_format = V4L2_PIX_FMT_NV21; //for 3rd party + + if(mSecCamera->setSnapshotPixelFormat(new_picture_format) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSnapshotPixelFormat(format(%d))", __FUNCTION__, new_picture_format); + ret = UNKNOWN_ERROR; + } + } + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + //JPEG image quality + int new_jpeg_quality = params.getInt("jpeg-quality"); + + if (new_jpeg_quality < 1 || new_jpeg_quality > 100) { + LOGE("ERR(%s): Invalid quality(%d))", __FUNCTION__, new_jpeg_quality); + + new_jpeg_quality = 100; + + mParameters.set("jpeg-quality", "100"); + } + + mSecCamera->setJpegQuality(new_jpeg_quality); +#else + //JPEG image quality + int new_jpeg_quality = params.getInt("jpeg-quality"); + if (new_jpeg_quality < 0) + { + LOGW("JPEG-image quality is not specified or is negative, defaulting to 100"); + new_jpeg_quality = 100; + mParameters.set("jpeg-quality", "100"); + } + mSecCamera->setJpegQuality(new_jpeg_quality); +#endif + + // JPEG thumbnail size + int new_jpeg_thumbnail_width = params.getInt("jpeg-thumbnail-width"); + int new_jpeg_thumbnail_height= params.getInt("jpeg-thumbnail-height"); + + if(0 < new_jpeg_thumbnail_width && 0 < new_jpeg_thumbnail_height) + { + if(mSecCamera->setJpegThumbnailSize(new_jpeg_thumbnail_width, new_jpeg_thumbnail_height) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setJpegThumbnailSize(width(%d), height(%d))", __FUNCTION__, new_jpeg_thumbnail_width, new_jpeg_thumbnail_height); + ret = UNKNOWN_ERROR; + } + } + + // frame rate + int new_frame_rate = params.getPreviewFrameRate(); + if(new_frame_rate < 5 || new_frame_rate > 30) + { + new_frame_rate = 30; + } + + mParameters.setPreviewFrameRate(new_frame_rate); + // Calculate how long to wait between frames. + mPreviewFrameRateMicrosec = (int)(1000000.0f / float(new_frame_rate)); + + LOGD("frame rate:%d, mPreviewFrameRateMicrosec:%d", new_frame_rate, mPreviewFrameRateMicrosec); + + mSecCamera->setFrameRate(new_frame_rate); + + //vt mode + int new_vtmode = params.getInt("vtmode"); + if(0 <= new_vtmode) + { + if(mSecCamera->setVTmode(new_vtmode) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setVTMode(%d)", __FUNCTION__, new_vtmode); + ret = UNKNOWN_ERROR; + } + } + + // rotation + int new_rotation = params.getInt("rotation"); + int new_exif_rotation = 1; + if(new_rotation != -1) + { + if(new_vtmode == SecCamera::VT_MODE_ON ) // vt preview rotation + { + LOGE("ERR(%s):VT mode is on. Rotate(%d))", __FUNCTION__, new_rotation); + + if(mSecCamera->SetRotate(new_rotation) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __FUNCTION__, new_rotation); + ret = UNKNOWN_ERROR; + } + } + else //exif orientation information + { + if(mSecCamera->SetRotate(0) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __FUNCTION__, new_rotation); + ret = UNKNOWN_ERROR; + } + + if(new_rotation == 0) + new_exif_rotation = 1; + else if (new_rotation == 90) + new_exif_rotation = 6; + else if (new_rotation == 180) + new_exif_rotation = 3; + else if (new_rotation == 270) + new_exif_rotation = 8; + else + new_exif_rotation = 1; + } + } + +#ifndef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + // brightness + int new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); + int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); + int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); + + if( (min_exposure_compensation <= new_exposure_compensation) && + (max_exposure_compensation >= new_exposure_compensation) ) + { + if(mSecCamera->setBrightness(new_exposure_compensation) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __FUNCTION__, new_exposure_compensation); + ret = UNKNOWN_ERROR; + } + + } + + // whitebalance + const char * new_white_str = params.get("whitebalance"); + if(new_white_str != NULL) + { + int new_white = -1; + + if(strcmp(new_white_str, "auto") == 0) + new_white = SecCamera::WHITE_BALANCE_AUTO; + else if(strcmp(new_white_str, "indoor3100") == 0) + new_white = SecCamera::WHITE_BALANCE_INDOOR3100; + else if(strcmp(new_white_str, "outdoor5100") == 0) + new_white = SecCamera::WHITE_BALANCE_OUTDOOR5100; + else if(strcmp(new_white_str, "indoor2000") == 0) + new_white = SecCamera::WHITE_BALANCE_INDOOR2000; + else if(strcmp(new_white_str, "halt") == 0) + new_white = SecCamera::WHITE_BALANCE_HALT; + else if(strcmp(new_white_str, "cloudy") == 0) + new_white = SecCamera::WHITE_BALANCE_CLOUDY; + else if(strcmp(new_white_str, "sunny") == 0) + new_white = SecCamera::WHITE_BALANCE_SUNNY; + else + { + LOGE("ERR(%s):Invalid white balance(%s)", __FUNCTION__, new_white_str); + ret = UNKNOWN_ERROR; + } + + if(0 <= new_white) + { + // white_balance + if(mSecCamera->setWhiteBalance(new_white) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __FUNCTION__, new_white); + ret = UNKNOWN_ERROR; + } + } + } + + // image effect + const char * new_image_effect_str = params.get("image-effects"); + if(new_image_effect_str != NULL) + { + int new_image_effect = -1; + + if(strcmp(new_image_effect_str, "original") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_ORIGINAL; + else if(strcmp(new_image_effect_str, "arbitrary") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_ARBITRARY; + else if(strcmp(new_image_effect_str, "negative") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_NEGATIVE; + else if(strcmp(new_image_effect_str, "freeze") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_FREEZE; + else if(strcmp(new_image_effect_str, "embossing") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_EMBOSSING; + else if(strcmp(new_image_effect_str, "silhouette") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_SILHOUETTE; + else + { + LOGE("ERR(%s):Invalid effect(%s)", __FUNCTION__, new_image_effect_str); + ret = UNKNOWN_ERROR; + } + + if(new_image_effect >= 0) + { + // white_balance + if(mSecCamera->setImageEffect(new_image_effect) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __FUNCTION__, new_image_effect); + ret = UNKNOWN_ERROR; + } + } + } + +#else + // scene mode + const char * new_scene_mode_str = params.get("scene-mode"); + + LOGV("%s() new_scene_mode_str %s", __FUNCTION__,new_scene_mode_str); + + if(new_scene_mode_str != NULL) + { + int new_scene_mode = -1; + + const char * new_iso_str = NULL; + const char * new_metering_str = NULL; + int new_exposure_compensation = 0; + const char * new_white_str = NULL; + int new_sharpness = 0; + int new_saturation = 0; + const char * new_focus_mode_str = NULL; + const char * new_flash_mode_str = NULL; + + if(strcmp(new_scene_mode_str, "auto") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_NONE; + + new_iso_str = params.get("iso"); + new_metering_str = params.get("metering"); + new_exposure_compensation = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); + new_white_str = params.get("whitebalance"); + new_sharpness = params.getInt("sharpness"); + new_saturation = params.getInt("saturation"); + new_focus_mode_str = params.get("focus-mode"); + new_flash_mode_str = params.get("flash-mode"); + } + else + { + if(strcmp(new_scene_mode_str, "portrait") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_PORTRAIT; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_MINUS_1); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "facedetect"); + } + else if(strcmp(new_scene_mode_str, "landscape") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_LANDSCAPE; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "matrix"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_PLUS_1); + mParameters.set("saturation", SecCamera::SATURATION_PLUS_1); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "sports") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_SPORTS; + + mParameters.set("iso", "sports"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "party") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_PARTY_INDOOR; + + mParameters.set("iso", "200"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_PLUS_1); + mParameters.set("focus-mode", "auto"); + } + else if((strcmp(new_scene_mode_str, "beach") == 0) || (strcmp(new_scene_mode_str, "snow") == 0)) + { + new_scene_mode = SecCamera::SCENE_MODE_BEACH_SNOW; + + mParameters.set("iso", "50"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_PLUS_2); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_PLUS_1); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "sunset") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_SUNSET; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "daylight"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "dusk-dawn") == 0) //added + { + new_scene_mode = SecCamera::SCENE_MODE_DUSK_DAWN; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "fluorescent"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "fall-color") == 0) //added + { + new_scene_mode = SecCamera::SCENE_MODE_FALL_COLOR; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_PLUS_2); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "night") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_NIGHTSHOT; + + mParameters.set("iso", "night"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "back-light") == 0) //added + { + const char * flash_mode_str = params.get("flash-mode"); + + new_scene_mode = SecCamera::SCENE_MODE_BACK_LIGHT; + + mParameters.set("iso", "auto"); + if(strcmp(flash_mode_str, "off") == 0) + mParameters.set("metering", "spot"); + else + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + } + else if(strcmp(new_scene_mode_str, "fireworks") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_FIREWORKS; + + mParameters.set("iso", "50"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else if(strcmp(new_scene_mode_str, "text") == 0) //added + { + new_scene_mode = SecCamera::SCENE_MODE_TEXT; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "auto"); + mParameters.set("sharpness", SecCamera::SHARPNESS_PLUS_2); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "macro"); + } + else if(strcmp(new_scene_mode_str, "candlelight") == 0) + { + new_scene_mode = SecCamera::SCENE_MODE_CANDLE_LIGHT; + + mParameters.set("iso", "auto"); + mParameters.set("metering", "center"); + mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, SecCamera::BRIGHTNESS_NORMAL); + mParameters.set("whitebalance", "daylight"); + mParameters.set("sharpness", SecCamera::SHARPNESS_NORMAL); + mParameters.set("saturation", SecCamera::SATURATION_NORMAL); + mParameters.set("focus-mode", "auto"); + mParameters.set("flash-mode", "off"); + } + else + { + LOGE("%s::unmatched scene_mode(%s)", __FUNCTION__, new_scene_mode_str); //action, night-portrait, theatre, steadyphoto + ret = UNKNOWN_ERROR; + } + + new_iso_str = mParameters.get("iso"); + new_metering_str = mParameters.get("metering"); + new_exposure_compensation = mParameters.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); + new_white_str = mParameters.get("whitebalance"); + new_sharpness = mParameters.getInt("sharpness"); + new_saturation = mParameters.getInt("saturation"); + new_focus_mode_str = mParameters.get("focus-mode"); + new_flash_mode_str = mParameters.get("flash-mode"); + } + + // 1. ISO + if(new_iso_str != NULL ) + { + int new_iso = -1; + if(strcmp(new_iso_str, "auto") == 0) + new_iso = SecCamera::ISO_AUTO; + else if(strcmp(new_iso_str, "50") == 0) + new_iso = SecCamera::ISO_50; + else if(strcmp(new_iso_str, "100") == 0) + new_iso = SecCamera::ISO_100; + else if(strcmp(new_iso_str, "200") == 0) + new_iso = SecCamera::ISO_200; + else if(strcmp(new_iso_str, "400") == 0) + new_iso = SecCamera::ISO_400; + else if(strcmp(new_iso_str, "800") == 0) + new_iso = SecCamera::ISO_800; + else if(strcmp(new_iso_str, "1600") == 0) + new_iso = SecCamera::ISO_1600; + else if(strcmp(new_iso_str, "sports") == 0) + new_iso = SecCamera::ISO_SPORTS; + else if(strcmp(new_iso_str, "night") == 0) + new_iso = SecCamera::ISO_NIGHT; + else if(strcmp(new_iso_str, "movie") == 0) + new_iso = SecCamera::ISO_MOVIE; + else + { + LOGE("%s::unmatched iso(%d)", __FUNCTION__, new_iso); + ret = UNKNOWN_ERROR; + } + if(0 <= new_iso) + { + if(mSecCamera->setISO(new_iso) < 0) + { + LOGE("%s::mSecCamera->setISO(%d) fail", __FUNCTION__, new_iso); + ret = UNKNOWN_ERROR; + } + } + } + + // 2. metering + if(new_metering_str != NULL ) + { + int new_metering = -1; + if(strcmp(new_metering_str, "matrix") == 0) + new_metering = SecCamera::METERING_MATRIX; + else if(strcmp(new_metering_str, "center") == 0) + new_metering = SecCamera::METERING_CENTER; + else if(strcmp(new_metering_str, "spot") == 0) + new_metering = SecCamera::METERING_SPOT; + else + { + LOGE("%s::unmatched metering(%s)", __FUNCTION__, new_metering_str); + ret = UNKNOWN_ERROR; + } + if(0 <= new_metering) + { + if(mSecCamera->setMetering(new_metering) < 0) + { + LOGE("%s::mSecCamera->setMetering(%d) fail", __FUNCTION__, new_metering); + ret = UNKNOWN_ERROR; + } + } + } + + // 3. brightness + int max_exposure_compensation = params.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); + int min_exposure_compensation = params.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); + + if( (min_exposure_compensation <= new_exposure_compensation) && + (max_exposure_compensation >= new_exposure_compensation) ) + { + if(mSecCamera->setBrightness(new_exposure_compensation) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setBrightness(brightness(%d))", __FUNCTION__, new_exposure_compensation); + ret = UNKNOWN_ERROR; + } + + } + + // 4. whitebalance + if(new_white_str != NULL) + { + int new_white = -1; + + if(strcmp(new_white_str, "auto") == 0) + new_white = SecCamera::WHITE_BALANCE_AUTO; + else if(strcmp(new_white_str, "daylight") == 0) + new_white = SecCamera::WHITE_BALANCE_DAYLIGHT; + else if((strcmp(new_white_str, "cloudy") == 0) || (strcmp(new_white_str, "cloudy-daylight") == 0)) + new_white = SecCamera::WHITE_BALANCE_CLOUDY; + else if(strcmp(new_white_str, "fluorescent") == 0) + new_white = SecCamera::WHITE_BALANCE_FLUORESCENT; + else if(strcmp(new_white_str, "incandescent") == 0) + new_white = SecCamera::WHITE_BALANCE_INCANDESCENT; + else + { + LOGE("ERR(%s):Invalid white balance(%s)", __FUNCTION__, new_white_str); //twilight, shade, warm_flourescent + ret = UNKNOWN_ERROR; + } + + if(0 <= new_white) + { + // white_balance + if(mSecCamera->setWhiteBalance(new_white) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setWhiteBalance(white(%d))", __FUNCTION__, new_white); + ret = UNKNOWN_ERROR; + } + } + } + + //5. sharpness + if(0 <= new_sharpness) + { + if(mSecCamera->setSharpness(new_sharpness) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSharpness(%d)", __FUNCTION__,new_sharpness); + ret = UNKNOWN_ERROR; + } + } + + //6. saturation + if(0 <= new_saturation) + { + if(mSecCamera->setSaturation(new_saturation) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSaturation(%d)", __FUNCTION__, new_saturation); + ret = UNKNOWN_ERROR; + } + } + + // 7. focus mode + if(new_focus_mode_str != NULL) + { + int new_focus_mode = -1; + + if((strcmp(new_focus_mode_str, "auto") == 0) || (strcmp(new_focus_mode_str, "fixed") == 0) ||(strcmp(new_focus_mode_str, "infinity") == 0)) + new_focus_mode = SecCamera::FOCUS_MODE_AUTO; + else if(strcmp(new_focus_mode_str, "macro") == 0) + new_focus_mode = SecCamera::FOCUS_MODE_MACRO; + else if(strcmp(new_focus_mode_str, "facedetect") == 0) + new_focus_mode = SecCamera::FOCUS_MODE_FACEDETECT; + else + { + LOGE("%s::unmatched focus_mode(%s)", __FUNCTION__, new_focus_mode_str); //infinity + ret = UNKNOWN_ERROR; + } + + if(0 <= new_focus_mode) + { + if(mSecCamera->setFocusMode(new_focus_mode) < 0) + { + LOGE("%s::mSecCamera->setFocusMode(%d) fail", __FUNCTION__, new_focus_mode); + ret = UNKNOWN_ERROR; + } + } + } + + // 8. flash.. + if(new_flash_mode_str != NULL ) + { + int new_flash_mode = -1; + if(strcmp(new_flash_mode_str, "off") == 0) + new_flash_mode = SecCamera::FLASH_MODE_OFF; + else if(strcmp(new_flash_mode_str, "auto") == 0) + new_flash_mode = SecCamera::FLASH_MODE_AUTO; + else if(strcmp(new_flash_mode_str, "on") == 0) + new_flash_mode = SecCamera::FLASH_MODE_ON; + else if(strcmp(new_flash_mode_str, "torch") == 0) + new_flash_mode = SecCamera::FLASH_MODE_TORCH; + else + { + LOGE("%s::unmatched flash_mode(%s)", __FUNCTION__, new_flash_mode_str); //red-eye + ret = UNKNOWN_ERROR; + } + if(0 <= new_flash_mode) + { + if(mSecCamera->setFlashMode(new_flash_mode) < 0) + { + LOGE("%s::mSecCamera->setFlashMode(%d) fail", __FUNCTION__, new_flash_mode); + ret = UNKNOWN_ERROR; + } + } + } + + // 9. scene.. + if(0 <= new_scene_mode) + { + if(mSecCamera->setSceneMode(new_scene_mode) < 0) + { + LOGE("%s::mSecCamera->setSceneMode(%d) fail", __FUNCTION__, new_scene_mode); + ret = UNKNOWN_ERROR; + } + } + } + +// --------------------------------------------------------------------------- + + // image effect + const char * new_image_effect_str = params.get("effect"); + if(new_image_effect_str != NULL) + { + int new_image_effect = -1; + + if((strcmp(new_image_effect_str, "auto") == 0) || (strcmp(new_image_effect_str, "none") == 0)) + new_image_effect = SecCamera::IMAGE_EFFECT_NONE; + else if((strcmp(new_image_effect_str, "bnw") == 0) || (strcmp(new_image_effect_str, "mono") == 0)) + new_image_effect = SecCamera::IMAGE_EFFECT_BNW; + else if(strcmp(new_image_effect_str, "sepia") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_SEPIA; + else if(strcmp(new_image_effect_str, "aqua") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_AQUA; + else if(strcmp(new_image_effect_str, "antique") == 0) //added at samsung + new_image_effect = SecCamera::IMAGE_EFFECT_ANTIQUE; + else if(strcmp(new_image_effect_str, "negative") == 0) + new_image_effect = SecCamera::IMAGE_EFFECT_NEGATIVE; + else if(strcmp(new_image_effect_str, "sharpen") == 0) //added at samsung + new_image_effect = SecCamera::IMAGE_EFFECT_SHARPEN; + else + { + LOGE("ERR(%s):Invalid effect(%s)", __FUNCTION__, new_image_effect_str); //posterize, whiteboard, blackboard, solarize + ret = UNKNOWN_ERROR; + } + + if(new_image_effect >= 0) + { + if(mSecCamera->setImageEffect(new_image_effect) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setImageEffect(effect(%d))", __FUNCTION__, new_image_effect); + ret = UNKNOWN_ERROR; + } + } + } + + //antiBanding + const char * new_antibanding_str = params.get("antibanding"); + if(new_antibanding_str != NULL) + { + int new_antibanding = -1; + + if(strcmp(new_antibanding_str,"auto") == 0) + new_antibanding = SecCamera::ANTI_BANDING_AUTO; + else if(strcmp(new_antibanding_str,"50hz") == 0) + new_antibanding = SecCamera::ANTI_BANDING_50HZ; + else if(strcmp(new_antibanding_str,"60hz") == 0) + new_antibanding = SecCamera::ANTI_BANDING_60HZ; + else if(strcmp(new_antibanding_str,"off") == 0) + new_antibanding = SecCamera::ANTI_BANDING_OFF; + else + { + LOGE("%s::unmatched antibanding(%s)", __FUNCTION__, new_antibanding_str); + ret = UNKNOWN_ERROR; + } + + if(0 <= new_antibanding) + { + if(mSecCamera->setAntiBanding(new_antibanding) < 0) + { + LOGE("%s::mSecCamera->setAntiBanding(%d) fail", __FUNCTION__, new_antibanding); + ret = UNKNOWN_ERROR; + } + } + + } + + //contrast + int new_contrast = params.getInt("contrast"); + if(0 <= new_contrast) + { + if(mSecCamera->setContrast(new_contrast) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setContrast(%d)", __FUNCTION__, new_contrast); + ret = UNKNOWN_ERROR; + } + } + + //WDR + int new_wdr = params.getInt("wdr"); + if(0 <= new_wdr) + { + if(mSecCamera->setWDR(new_wdr) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __FUNCTION__, new_wdr); + ret = UNKNOWN_ERROR; + } + } + + //anti shake + int new_anti_shake = params.getInt("anti-shake"); + if(0 <= new_anti_shake) + { + if(mSecCamera->setAntiShake(new_anti_shake) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setWDR(%d)", __FUNCTION__, new_anti_shake); + ret = UNKNOWN_ERROR; + } + } + + //zoom + int new_zoom_level = params.getInt(CameraParameters::KEY_ZOOM); + if(0 <= new_zoom_level) + { + if(mSecCamera->setZoom(new_zoom_level) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setZoom(%d)", __FUNCTION__, new_zoom_level); + ret = UNKNOWN_ERROR; + } + } + + //object tracking + int new_obj_tracking = params.getInt("obj-tracking"); + if(0 <= new_obj_tracking) + { + if(mSecCamera->setObjectTracking(new_obj_tracking) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setObjectTracking(%d)", __FUNCTION__, new_obj_tracking); + ret = UNKNOWN_ERROR; + } + } + + // smart auto + int new_smart_auto = params.getInt("smart-auto"); + if(0 <= new_smart_auto) + { + if(mSecCamera->setSmartAuto(new_smart_auto) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSmartAuto(%d)", __FUNCTION__, new_smart_auto); + ret = UNKNOWN_ERROR; + } + + //smart auto on => start Smartautoscene Thread + if(mSecCamera->getSmartAuto() == 1) + { + if(startSmartautoscene() == INVALID_OPERATION) + { + LOGE("Smartautoscene thread is already running"); + } + else + LOGE("Smartautoscene thread start"); + } + //smart auto off => stop Smartautoscene Thread + else + { + if(mSmartautosceneRunning == true) + { + stopSmartautoscene(); + LOGV("Smartautoscene thread stop"); + } + else + LOGV("Smartautoscene thread was already stop"); + } + } + + // beauty_shot + int new_beauty_shot = params.getInt("face_beauty"); + if(0 <= new_beauty_shot) + { + if(mSecCamera->setBeautyShot(new_beauty_shot) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setBeautyShot(%d)", __FUNCTION__, new_beauty_shot); + ret = UNKNOWN_ERROR; + } + } + + // vintage mode + const char * new_vintage_mode_str = params.get("vintagemode"); + if(new_vintage_mode_str != NULL) + { + int new_vintage_mode = -1; + + if(strcmp(new_vintage_mode_str, "off") == 0) + new_vintage_mode = SecCamera::VINTAGE_MODE_OFF; + else if(strcmp(new_vintage_mode_str, "normal") == 0) + new_vintage_mode = SecCamera::VINTAGE_MODE_NORMAL; + else if(strcmp(new_vintage_mode_str, "warm") == 0) + new_vintage_mode = SecCamera::VINTAGE_MODE_WARM; + else if(strcmp(new_vintage_mode_str, "cool") == 0) + new_vintage_mode = SecCamera::VINTAGE_MODE_COOL; + else if(strcmp(new_vintage_mode_str, "bnw") == 0) + new_vintage_mode = SecCamera::VINTAGE_MODE_BNW; + else + { + LOGE("%s::unmatched vintage_mode(%d)", __FUNCTION__, new_vintage_mode); + ret = UNKNOWN_ERROR; + } + + if(0 <= new_vintage_mode) + { + if(mSecCamera->setVintageMode(new_vintage_mode) < 0) + { + LOGE("%s::mSecCamera->setVintageMode(%d) fail", __FUNCTION__, new_vintage_mode); + ret = UNKNOWN_ERROR; + } + } + } + + // gps latitude + const char * new_gps_latitude_str = params.get("gps-latitude"); + if(mSecCamera->setGPSLatitude(new_gps_latitude_str) < 0) + { + LOGE("%s::mSecCamera->setGPSLatitude(%s) fail", __FUNCTION__, new_gps_latitude_str); + ret = UNKNOWN_ERROR; + } + + // gps longitude + const char * new_gps_longitute_str = params.get("gps-longitude"); + if(mSecCamera->setGPSLongitude(new_gps_longitute_str) < 0) + { + LOGE("%s::mSecCamera->setGPSLongitude(%s) fail", __FUNCTION__, new_gps_longitute_str); + ret = UNKNOWN_ERROR; + } + + // gps altitude + const char * new_gps_altitude_str = params.get("gps-altitude"); + if(mSecCamera->setGPSAltitude(new_gps_altitude_str) < 0) + { + LOGE("%s::mSecCamera->setGPSAltitude(%s) fail", __FUNCTION__, new_gps_altitude_str); + ret = UNKNOWN_ERROR; + } + + // gps timestamp + const char * new_gps_timestamp_str = params.get("gps-timestamp"); + if(mSecCamera->setGPSTimeStamp(new_gps_timestamp_str) < 0) + { + LOGE("%s::mSecCamera->setGPSTimeStamp(%s) fail", __FUNCTION__, new_gps_timestamp_str); + ret = UNKNOWN_ERROR; + } + + // Recording size + int new_recording_width = params.getInt("recording-size-width"); + int new_recording_height= params.getInt("recording-size-height"); + + if(0 < new_recording_width && 0 < new_recording_height) { + if(mSecCamera->setRecordingSize(new_recording_width, new_recording_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __FUNCTION__, new_recording_width, new_recording_height); + ret = UNKNOWN_ERROR; + } + } + + else { + if(mSecCamera->setRecordingSize(new_preview_width, new_preview_height) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setRecordingSize(width(%d), height(%d))", __FUNCTION__, new_preview_width, new_preview_height); + ret = UNKNOWN_ERROR; + } + } + + //gamma + const char * new_gamma_str = params.get("video_recording_gamma"); + if(new_gamma_str != NULL) + { + int new_gamma = -1; + + if(strcmp(new_gamma_str, "off") == 0) + new_gamma = SecCamera::GAMMA_OFF; + else if(strcmp(new_gamma_str, "on") == 0) + new_gamma = SecCamera::GAMMA_ON; + else + { + LOGE("%s::unmatched gamma(%s)", __FUNCTION__, new_gamma_str); + ret = UNKNOWN_ERROR; + } + + if(0 <= new_gamma) + { + if(mSecCamera->setGamma(new_gamma) < 0) + { + LOGE("%s::mSecCamera->setGamma(%d) fail", __FUNCTION__, new_gamma); + ret = UNKNOWN_ERROR; + } + } + } + + //slow ae + const char * new_slow_ae_str = params.get("slow_ae"); + if(new_slow_ae_str != NULL) + { + int new_slow_ae = -1; + + if(strcmp(new_slow_ae_str, "off") == 0) + new_slow_ae = SecCamera::SLOW_AE_OFF; + else if(strcmp(new_slow_ae_str, "on") == 0) + new_slow_ae = SecCamera::SLOW_AE_ON; + else + { + LOGE("%s::unmatched slow_ae(%s)", __FUNCTION__, new_slow_ae_str); + ret = UNKNOWN_ERROR; + } + + if(0 <= new_slow_ae) + { + if(mSecCamera->setSlowAE(new_slow_ae) < 0) + { + LOGE("%s::mSecCamera->setSlowAE(%d) fail", __FUNCTION__, new_slow_ae); + ret = UNKNOWN_ERROR; + } + } + } + + //exif orientation info + int new_exif_orientation = params.getInt("exifOrientation"); //kidggang + if(0 <= new_exif_orientation) + { + if(mSecCamera->setExifOrientationInfo(new_exif_orientation) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __FUNCTION__, new_exif_orientation); + ret = UNKNOWN_ERROR; + } + } + + /*Camcorder fix fps*/ + int new_sensor_mode = params.getInt("cam_mode"); + if(0 <= new_sensor_mode) + { + if(mSecCamera->setSensorMode(new_sensor_mode) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setSensorMode(%d)", __FUNCTION__, new_sensor_mode); + ret = UNKNOWN_ERROR; + } + } + else + { + new_sensor_mode=0; + } + + /*Shot mode*/ + int new_shot_mode = params.getInt("shot_mode"); + if(0 <= new_shot_mode) + { + if(mSecCamera->setShotMode(new_shot_mode) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setShotMode(%d)", __FUNCTION__, new_shot_mode); + ret = UNKNOWN_ERROR; + } + } + else + { + new_shot_mode=0; + } + + //blur for Video call + int new_blur_level = params.getInt("blur"); + if(0 <= new_blur_level) + { + if(mSecCamera->setBlur(new_blur_level) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setBlur(%d)", __FUNCTION__, new_blur_level); + ret = UNKNOWN_ERROR; + } + } + + + // chk_dataline + int new_dataline = params.getInt("chk_dataline"); + if(0 <= new_dataline) + { + if(mSecCamera->setDataLineCheck(new_dataline) < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setDataLineCheck(%d)", __FUNCTION__, new_dataline); + ret = UNKNOWN_ERROR; + } + } + + //Batch Command + if(new_camera_id == SecCamera::CAMERA_ID_BACK) + { + if(mSecCamera->setBatchReflection() < 0) + { + LOGE("ERR(%s):Fail on mSecCamera->setBatchCmd", __FUNCTION__); + ret = UNKNOWN_ERROR; + } + } +#endif + + return ret; +} + +CameraParameters CameraHardwareSec::getParameters() const +{ + LOGV("%s()", __FUNCTION__); + Mutex::Autolock lock(mLock); + return mParameters; +} + +status_t CameraHardwareSec::sendCommand(int32_t command, int32_t arg1, int32_t arg2) +{ +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + LOGV("%s() : command = %d, arg1 =%d, arg2= %d", __FUNCTION__,command, arg1, arg2); + switch(command) + { + case COMMAND_AE_AWB_LOCK_UNLOCK: + mSecCamera->setAEAWBLockUnlock(arg1, arg2); + break; + case COMMAND_FACE_DETECT_LOCK_UNLOCK: + mSecCamera->setFaceDetectLockUnlock(arg1); + break; + case COMMAND_OBJECT_POSITION: + mSecCamera->setObjectPosition(arg1, arg2); + break; + case COMMAND_OBJECT_TRACKING_STARTSTOP: + mSecCamera->setObjectTrackingStartStop(arg1); + objectTracking(arg1); + break; + case CONTINUOUS_SHOT_START_CAPTURE: + break; + case CONTINUOUS_SHOT_STOP_AND_ENCODING: + mSecCamera->setAEAWBLockUnlock(arg1, arg2); + LOGV("Continuous shot command received"); + break; + case COMMAND_TOUCH_AF_STARTSTOP: + mSecCamera->setTouchAFStartStop(arg1); + break; + case COMMAND_CHECK_DATALINE: + mSecCamera->setDataLineCheckStop(); + break; + case COMMAND_DEFAULT_IMEI: + mSecCamera->setDefultIMEI(arg1); + break; + defualt: + LOGV("%s()", __FUNCTION__); + break; + } + + return NO_ERROR; +#else + return BAD_VALUE; +#endif +} + +void CameraHardwareSec::release() +{ + LOGV("%s()", __FUNCTION__); +} + +wp<CameraHardwareInterface> CameraHardwareSec::singleton; + +sp<CameraHardwareInterface> CameraHardwareSec::createInstance() +{ + LOGV("%s()", __FUNCTION__); + if (singleton != 0) { + sp<CameraHardwareInterface> hardware = singleton.promote(); + if (hardware != 0) { + return hardware; + } + } + sp<CameraHardwareInterface> hardware(new CameraHardwareSec()); + singleton = hardware; + return hardware; +} +#if 0 +extern "C" sp<CameraHardwareInterface> openCameraHardware() +{ + LOGV("%s()", __FUNCTION__); + return CameraHardwareSec::createInstance(); +} +#endif + +static CameraInfo sCameraInfo[] = { + { + CAMERA_FACING_BACK, + 90, /* orientation */ + } +}; + +extern "C" int HAL_getNumberOfCameras() +{ + return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]); +} + +extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) +{ + memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo)); +} + +extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId) +{ + return CameraHardwareSec::createInstance(); +} + +}; // namespace android diff --git a/libcamera/SecCameraHWInterface.h b/libcamera/SecCameraHWInterface.h new file mode 100644 index 0000000..9e4fb79 --- /dev/null +++ b/libcamera/SecCameraHWInterface.h @@ -0,0 +1,257 @@ +/* +** +** Copyright 2008, The Android Open Source Project +** +** 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 on 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. +*/ + +#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H +#define ANDROID_HARDWARE_CAMERA_HARDWARE_SEC_H + +#include "SecCamera.h" +#include <utils/threads.h> +#include <camera/CameraHardwareInterface.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> +#include <utils/threads.h> + +namespace android { +class CameraHardwareSec : public CameraHardwareInterface { +public: + virtual sp<IMemoryHeap> getPreviewHeap() const; + virtual sp<IMemoryHeap> getRawHeap() const; + +//Kamat --eclair + virtual void setCallbacks(notify_callback notify_cb, + data_callback data_cb, + data_callback_timestamp data_cb_timestamp, + void* user); + + virtual void enableMsgType(int32_t msgType); + virtual void disableMsgType(int32_t msgType); + virtual bool msgTypeEnabled(int32_t msgType); + + virtual status_t startPreview(); + virtual void stopPreview(); + virtual bool previewEnabled(); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + virtual status_t startSmartautoscene(); + virtual void stopSmartautoscene(); + virtual bool smartautosceneEnabled(); +#endif + + virtual status_t startRecording(); + virtual void stopRecording(); + virtual bool recordingEnabled(); + virtual void releaseRecordingFrame(const sp<IMemory>& mem); + + virtual status_t autoFocus(); + virtual status_t cancelAutoFocus(); + virtual status_t takePicture(); + virtual status_t cancelPicture(); + virtual status_t dump(int fd, const Vector<String16>& args) const; + virtual status_t setParameters(const CameraParameters& params); + virtual CameraParameters getParameters() const; + virtual status_t sendCommand(int32_t command, int32_t arg1, + int32_t arg2); + virtual void release(); + + static sp<CameraHardwareInterface> createInstance(); + +private: + CameraHardwareSec(); + virtual ~CameraHardwareSec(); + + static wp<CameraHardwareInterface> singleton; + + static const int kBufferCount = MAX_BUFFERS; + static const int kBufferCountForRecord = MAX_BUFFERS; + + class PreviewThread : public Thread { + CameraHardwareSec* mHardware; + public: + PreviewThread(CameraHardwareSec* hw): +#ifdef SINGLE_PROCESS + // In single process mode this thread needs to be a java thread, + // since we won't be calling through the binder. + Thread(true), +#else + Thread(false), +#endif + mHardware(hw) { } + virtual void onFirstRef() { + run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + int ret = mHardware->previewThread(); + // loop until we need to quit + if(ret == NO_ERROR) + return true; + else + return false; + } + }; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + class SmartautosceneThread : public Thread { + CameraHardwareSec* mHardware; + public: + SmartautosceneThread(CameraHardwareSec* hw): +#ifdef SINGLE_PROCESS + // In single process mode this thread needs to be a java thread, + // since we won't be calling through the binder. + Thread(true), +#else + Thread(false), +#endif + mHardware(hw) { } + virtual void onFirstRef() { + run("CameraSmartautosceneThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + int ret = mHardware->smartautosceneThread(); + // loop until we need to quit + if(ret == NO_ERROR) + return true; + else + return false; + } + }; +#endif + void initDefaultParameters(); + void initHeapLocked(); + + int previewThread(); +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + int smartautosceneThread(); +#endif + + static int beginAutoFocusThread(void *cookie); + int autoFocusThread(); + + static int beginPictureThread(void *cookie); + int pictureThread(); + int save_jpeg( unsigned char * real_jpeg, int jpeg_size); + void save_postview(const char *fname, uint8_t *buf, uint32_t size); + int decodeInterleaveData(unsigned char *pInterleaveData, + int interleaveDataSize, + int yuvWidth, + int yuvHeight, + int *pJpegSize, + void *pJpegData, + void *pYuvData); + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + static int beginObjectTrackingThread(void *cookie); + int objectTrackingThread(); + status_t objectTracking(int onoff); +#endif + + mutable Mutex mLock; + + CameraParameters mParameters; + + sp<MemoryHeapBase> mPreviewHeap; + sp<MemoryHeapBase> mRawHeap; + sp<MemoryHeapBase> mRecordHeap; + sp<MemoryHeapBase> mJpegHeap; + sp<MemoryBase> mBuffers[kBufferCount]; + sp<MemoryBase> mRecordBuffers[kBufferCountForRecord]; + + SecCamera *mSecCamera; + bool mPreviewRunning; + int mPreviewFrameSize; + int mRawFrameSize; + int mPreviewFrameRateMicrosec; + + + // protected by mLock + sp<PreviewThread> mPreviewThread; +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + sp<SmartautosceneThread> mSmartautosceneThread; +#endif + notify_callback mNotifyCb; + data_callback mDataCb; + data_callback_timestamp mDataCbTimestamp; + void *mCallbackCookie; + + int32_t mMsgEnabled; + + // only used from PreviewThread + int mCurrentPreviewFrame; + int mCurrentRecordFrame; + + bool mRecordRunning; +#ifdef JPEG_FROM_SENSOR + int mPostViewWidth; + int mPostViewHeight; + int mPostViewSize; +#endif + + int mNoHwHandle; + struct timeval mTimeStart; + struct timeval mTimeStop; + +#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION + enum COMMAND_DEFINE + { + COMMAND_AE_AWB_LOCK_UNLOCK = 1101, + COMMAND_FACE_DETECT_LOCK_UNLOCK = 1102, + COMMAND_OBJECT_POSITION = 1103, + COMMAND_OBJECT_TRACKING_STARTSTOP = 1104, + COMMAND_TOUCH_AF_STARTSTOP = 1105, + COMMAND_CHECK_DATALINE = 1106, + CONTINUOUS_SHOT_START_CAPTURE = 1023, + CONTINUOUS_SHOT_STOP_AND_ENCODING = 1024, + COMMAND_DEFAULT_IMEI = 1107, + }; + +class ObjectTrackingThread : public Thread { + CameraHardwareSec* mHardware; + public: + ObjectTrackingThread(CameraHardwareSec* hw): +#ifdef SINGLE_PROCESS + // In single process mode this thread needs to be a java thread, + // since we won't be calling through the binder. + Thread(true), +#else + Thread(false), +#endif + mHardware(hw) { } + virtual void onFirstRef() { + run("CameraObjectTrackingThread", PRIORITY_URGENT_DISPLAY); + } + virtual bool threadLoop() { + int ret = mHardware->objectTrackingThread(); + // loop until we need to quit + if(ret == NO_ERROR) + return true; + else + return false; + } + }; + bool mObjectTrackingRunning; + sp<ObjectTrackingThread> mObjectTrackingThread; + int mObjectTrackingStatus; + + bool mSmartautosceneRunning; + int mSmartautoscene_current_status; + int mSmartautoscene_previous_status; + int af_thread_status; +#endif +}; + +}; // namespace android + +#endif |