summaryrefslogtreecommitdiff
path: root/camerasrc/src/camerasrc-internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'camerasrc/src/camerasrc-internal.c')
-rw-r--r--camerasrc/src/camerasrc-internal.c1463
1 files changed, 1463 insertions, 0 deletions
diff --git a/camerasrc/src/camerasrc-internal.c b/camerasrc/src/camerasrc-internal.c
new file mode 100644
index 0000000..e820bd9
--- /dev/null
+++ b/camerasrc/src/camerasrc-internal.c
@@ -0,0 +1,1463 @@
+/*
+ * camerasrc
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jeongmo Yang <jm80.yang@samsung.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <math.h>
+#include "camerasrc-internal.h"
+
+/*#define USE_IOCTL_DEBUG*/
+#if defined (USE_IOCTL_DEBUG)
+static char* get_request_name(int request, char* res_str) {
+ switch (request) {
+ case VIDIOC_QBUF:
+ sprintf(res_str, "[VIDIOC_QBUF]");
+ break;
+ case VIDIOC_DQBUF:
+ sprintf(res_str, "[VIDIOC_DQBUF]");
+ break;
+ case VIDIOC_S_INPUT:
+ sprintf(res_str, "[VIDIOC_S_INPUT]");
+ break;
+ case VIDIOC_G_INPUT:
+ sprintf(res_str, "[VIDIOC_G_INPUT]");
+ break;
+ case VIDIOC_S_PARM:
+ sprintf(res_str, "[VIDIOC_S_PARM]");
+ break;
+ case VIDIOC_G_PARM:
+ sprintf(res_str, "[VIDIOC_G_PARM]");
+ break;
+ case VIDIOC_S_FMT:
+ sprintf(res_str, "[VIDIOC_S_FMT]");
+ break;
+ case VIDIOC_G_FMT:
+ sprintf(res_str, "[VIDIOC_G_FMT]");
+ break;
+ case VIDIOC_REQBUFS:
+ sprintf(res_str, "[VIDIOC_REQBUFS]");
+ break;
+ case VIDIOC_QUERYBUF:
+ sprintf(res_str, "[VIDIOC_QUERYBUF]");
+ break;
+ case VIDIOC_STREAMON:
+ sprintf(res_str, "[VIDIOC_STREAMON]");
+ break;
+ case VIDIOC_STREAMOFF:
+ sprintf(res_str, "[VIDIOC_STREAMOFF]");
+ break;
+ case VIDIOC_S_CTRL:
+ sprintf(res_str, "[VIDIOC_S_CTRL] ");
+ break;
+ case VIDIOC_G_CTRL:
+ sprintf(res_str, "[VIDIOC_G_CTRL]");
+ break;
+ case VIDIOC_ENUMINPUT:
+ sprintf(res_str, "[VIDIOC_ENUMINPUT]");
+ break;
+ case VIDIOC_S_JPEGCOMP:
+ sprintf(res_str, "[VIDIOC_S_JPEGCOMP]");
+ break;
+ case VIDIOC_G_JPEGCOMP:
+ sprintf(res_str, "[VIDIOC_G_JPEGCOMP]");
+ break;
+ /* Extension */
+ case VIDIOC_S_STROBE:
+ sprintf(res_str, "[VIDIOC_S_STROBE]");
+ break;
+ case VIDIOC_G_STROBE:
+ sprintf(res_str, "[VIDIOC_G_STROBE]");
+ break;
+ case VIDIOC_S_RECOGNITION:
+ sprintf(res_str, "[VIDIOC_S_RECOGNITION]");
+ break;
+ case VIDIOC_G_RECOGNITION:
+ sprintf(res_str, "[VIDIOC_G_RECOGNITION]");
+ break;
+ case VIDIOC_G_EXIF:
+ sprintf(res_str, "[VIDIOC_G_EXIF]");
+ break;
+ default:
+ sprintf(res_str, "[UNKNOWN IOCTL(%x)]", request);
+ break;
+ }
+
+ return 0;
+}
+
+#define PRINT_IOCTL_INFO(request, arg) {\
+ char res_str[255];\
+ get_request_name(request, res_str);\
+ camsrc_info("[request : %s, argument address : %x]", res_str, arg);\
+}
+#else
+
+#define PRINT_IOCTL_INFO(request, arg)
+
+#endif
+
+
+#define LOCK(x) {\
+ if(0 != pthread_mutex_lock(&(x->mutex))) {\
+ camsrc_error("Mutex lock error");\
+ camsrc_assert(0);\
+ }\
+}
+
+#define UNLOCK(x) {\
+ if(0 != pthread_mutex_unlock(&(x->mutex))) {\
+ camsrc_error("Mutex unlock error");\
+ camsrc_assert(0);\
+ }\
+}
+
+#define AF_MUT_LOCK(p) {\
+ if(0 != pthread_mutex_lock(&(p->af_mutex))) {\
+ camsrc_error("AF Mutex locking error");\
+ camsrc_assert(0);\
+ }\
+}
+
+#define AF_MUT_UNLOCK(p) {\
+ if(0 != pthread_mutex_unlock(&(p->af_mutex))) {\
+ camsrc_error("AF Mutex unlocking error");\
+ camsrc_assert(0);\
+ }\
+}
+
+#define SET_CTRL_VAL(cid, in_value) {\
+ int err = CAMERASRC_ERR_UNKNOWN;\
+ struct v4l2_control control;\
+ control.id = cid;\
+ control.value = in_value;\
+ camsrc_info("[VIDIOC_S_CTRL] >> [%x] request with value %d", cid, in_value); \
+ err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control);\
+ if(err != CAMERASRC_SUCCESS) {\
+ return err;\
+ }\
+}
+
+#define GET_CTRL_VAL(cid, ret_value) {\
+ int err = CAMERASRC_ERR_UNKNOWN;\
+ struct v4l2_control control;\
+ control.id = cid;\
+ err = _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &control);\
+ if(err != CAMERASRC_SUCCESS) {\
+ return err;\
+ }\
+ ret_value = control.value;\
+ camsrc_info("[VIDIOC_G_CTRL] << [%x] request with value %d", cid, ret_value); \
+}
+
+#define SET_CTRL_VAL_ERR(cid, in_value, err) {\
+ struct v4l2_control control;\
+ control.id = cid;\
+ control.value = in_value;\
+ camsrc_info("[VIDIOC_S_CTRL] >> [%x] request with value %d", cid, in_value); \
+ _camerasrc_ioctl_with_err(handle, VIDIOC_S_CTRL, &control, &err);\
+}
+
+#define GET_CTRL_VAL_ERR(cid, ret_value, err) {\
+ struct v4l2_control control;\
+ control.id = cid;\
+ _camerasrc_ioctl_with_err(handle, VIDIOC_G_CTRL, &control, &err);\
+ ret_value = control.value;\
+ camsrc_info("[VIDIOC_G_CTRL] << [%x] request with value %d", cid, ret_value); \
+}
+
+/* AF function */
+static int _camerasrc_start_autofocusing(camerasrc_handle_t *handle);
+static int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle);
+static int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle);
+static int _camerasrc_release_autofocusing(camerasrc_handle_t *handle);
+
+
+int static af_retry_cnt = 0;
+
+static int _camerasrc_ioctl(camerasrc_handle_t *handle, int request, void *arg)
+{
+ int fd = handle->dev_fd;
+ int err;
+ int nAgain = 10;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+
+ LOCK(handle);
+
+ if (handle->check_esd == 1) {
+ camsrc_warning("ESD shock occured. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) {
+ camsrc_warning("Device emergency closed. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ PRINT_IOCTL_INFO(request, arg);
+
+again:
+ do {
+ err = ioctl (fd, request, arg);
+ } while (-1 == err && EINTR == errno);
+
+ if (err != 0) {
+ handle->errnum = errno;
+ err = errno;
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_error("ioctl[%x] err : %s", request, err_msg);
+ if (err == EEXIST) {
+ camsrc_info("EEXIST occured, but can go.");
+ err = 0;
+ } else if (err == ENOENT) {
+ camsrc_info("ENOENT occured, but can go.");
+ err = 0;
+#if defined (ENABLE_Q_ERROR)
+#warning "ENABLE_Q_ERROR enabled"
+ } else if (request == VIDIOC_DQBUF) {
+ goto DQ_ERROR;
+ } else if (request == VIDIOC_QBUF) {
+ goto ENQ_ERROR;
+#endif
+ } else if (err == EINVAL) {
+ camsrc_error("EINVAL occured, Shutdown");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INVALID_PARAMETER;
+ } else if (err == EBUSY) {
+ camsrc_error("EBUSY occured, Shutdown");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_PRIVILEGE;
+ } else if (err == EAGAIN && nAgain--) {
+ goto again;
+ } else {
+ /* Why does this return SUCCESS? */
+ camsrc_error("Unhandled exception occured on IOCTL");
+ }
+ }
+
+ UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+
+#if defined (ENABLE_Q_ERROR)
+DQ_ERROR:
+ camsrc_error("DQ Frame error occured");
+ printf("DQ Frame error occured");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INTERNAL;
+
+ENQ_ERROR:
+ camsrc_error("Q Frame error occured");
+ printf("Q Frame error occured");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INTERNAL;
+#endif
+}
+
+
+static int _camerasrc_ioctl_with_err(camerasrc_handle_t *handle, int request, void *arg, int *error)
+{
+ int fd = handle->dev_fd;
+ int err;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+
+ LOCK(handle);
+
+ *error = 0;
+
+ if (handle->check_esd == 1) {
+ camsrc_warning("ESD shock occured. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) {
+ camsrc_warning("Device emergency closed. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ PRINT_IOCTL_INFO(request, arg);
+
+ do {
+ err = ioctl (fd, request, arg);
+ } while (-1 == err && EINTR == errno);
+
+ if (err != 0) {
+ handle->errnum = errno;
+ *error = errno;
+ strerror_r(*error, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_error("ioctl[%x] err : %s", request, err_msg);
+ UNLOCK(handle);
+ return CAMERASRC_ERR_IO_CONTROL;
+ }
+
+ UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+}
+
+
+static int _camerasrc_ioctl_once(camerasrc_handle_t *handle, int request, void *arg)
+{
+ int fd = handle->dev_fd;
+ int err = -1;
+ int nAgain = 10;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+
+ LOCK(handle);
+
+ if (handle->check_esd == 1) {
+ camsrc_warning("ESD shock occured. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ if (handle->dev_fd == CAMERASRC_DEV_FD_EMERGENCY_CLOSED) {
+ camsrc_warning("Device emergency closed. All device control will success");
+ UNLOCK(handle);
+ return CAMERASRC_SUCCESS;
+ }
+
+ PRINT_IOCTL_INFO(request, arg);
+
+again:
+ err = ioctl (fd, request, arg);
+
+ if (err != 0) {
+ handle->errnum = errno;
+ err = errno;
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_error("ioctl[%x] err : %s", request, err_msg);
+ if (err == EEXIST) {
+ camsrc_info("EEXIST occured, but can go.");
+ err = 0;
+ } else if (err == ENOENT) {
+ camsrc_info("ENOENT occured, but can go.");
+ err = 0;
+#if defined (ENABLE_Q_ERROR)
+#warning "ENABLE_Q_ERROR enabled"
+ } else if (request == VIDIOC_DQBUF) {
+ goto DQ_ERROR;
+ } else if (request == VIDIOC_QBUF) {
+ goto ENQ_ERROR;
+#endif
+ } else if (err == EINVAL) {
+ camsrc_error("EINVAL occured, Shutdown");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INVALID_PARAMETER;
+ } else if (err == EAGAIN && nAgain--) {
+ goto again;
+ } else {
+ camsrc_error("Unhandled exception occured on IOCTL");
+ }
+ }
+
+ UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+
+#if defined (ENABLE_Q_ERROR)
+DQ_ERROR:
+ camsrc_error("DQ Frame error occured");
+ printf("DQ Frame error occured");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INTERNAL;
+
+ENQ_ERROR:
+ camsrc_error("Q Frame error occured");
+ printf("Q Frame error occured");
+ UNLOCK(handle);
+ return CAMERASRC_ERR_INTERNAL;
+#endif
+}
+
+
+static int _camerasrc_skip_frame(camerasrc_handle_t *handle, long int timeout, int skip_frame)
+{
+ camerasrc_handle_t *p = NULL;
+ int err = CAMERASRC_ERR_UNKNOWN;
+ fd_set fds;
+ struct timeval tv;
+ int r;
+ int skip_frame_num = skip_frame;
+
+ camsrc_error("enter");
+
+ p = handle;
+
+ while (skip_frame_num--) {
+ camsrc_error("SKIP FRAME #%d", skip_frame-skip_frame_num+1);
+
+ struct v4l2_buffer buf;
+
+ FD_ZERO (&fds);
+ FD_SET (p->dev_fd, &fds);
+
+ camsrc_error("************Still capture wait frame start");
+
+ /* Timeout. */
+ tv.tv_sec = (long int)timeout/1000;
+ tv.tv_usec = timeout - tv.tv_sec * 1000;
+
+ r = select (p->dev_fd + 1, &fds, NULL, NULL, &tv);
+
+ if (-1 == r) {
+ if (EINTR == errno) {
+ return CAMERASRC_SUCCESS;
+ }
+ camsrc_error("select() failed.");
+ return CAMERASRC_ERR_INTERNAL;
+ }
+
+ if (0 == r) {
+ camsrc_error("select() timeout.");
+ return CAMERASRC_ERR_DEVICE_WAIT_TIMEOUT;
+ }
+
+ /**@note from samsung camera sample. *****************************************/
+ /*SKIP FRAME START*/
+ CLEAR(buf);
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = p->buffer_idx;
+
+ if (-1 == _camerasrc_ioctl (p, VIDIOC_DQBUF, &buf)) {
+ switch (errno) {
+ case EAGAIN:
+ camsrc_info("VIDIOC_DQBUF [EAGAIN]");
+ return CAMERASRC_SUCCESS;
+ case EIO:
+ /* Could ignore EIO, see spec. */
+ /* fall through */
+ camsrc_info("VIDIOC_DQBUF [EIO]");
+ default:
+ camsrc_info("VIDIOC_DQBUF [%d]", errno);
+ return CAMERASRC_ERR_IO_CONTROL;
+ }
+ }
+
+ if (-1 == _camerasrc_ioctl (p, VIDIOC_QBUF, &buf)) {
+ return CAMERASRC_ERR_IO_CONTROL;
+ }
+ }
+
+ camsrc_error("leave");
+ err = CAMERASRC_SUCCESS;
+
+ return err;
+}
+
+static int _camerasrc_init_autofocusing_mode(camerasrc_handle_t *handle)
+{
+ int ctrl_id = V4L2_CID_FOCUS_AUTO_MODE;
+ int mode;
+
+ camsrc_info("enter");
+
+ if (handle->af_status == CAMERASRC_AUTO_FOCUS_STATUS_ONGOING) {
+ camsrc_info("Dev BUSY. Init failed.");
+ return CAMERASRC_ERR_INVALID_STATE;
+ }
+
+ switch (handle->cur_af_mode) {
+ case CAMERASRC_AF_MODE_AUTO:
+ mode = V4L2_FOCUS_AUTO_NORMAL;
+ camsrc_info("ON AUTOFOCUSING...BY AUTO");
+ break;
+ case CAMERASRC_AF_MODE_MANUAL:
+ ctrl_id = V4L2_CID_FOCUS_MODE;
+ mode = V4L2_FOCUS_MODE_MANUAL;
+ camsrc_info("ON AUTOFOCUSING...BY MANUAL");
+ break;
+ case CAMERASRC_AF_MODE_CONTINUOUS:
+ mode = V4L2_FOCUS_AUTO_CONTINUOUS;
+ camsrc_info("ON AUTOFOCUSING...BY CONTINUOUS");
+ if (handle->format.pix_format != CAMERASRC_PIX_NV12 &&
+ handle->format.pix_format != CAMERASRC_PIX_SN12) {
+ camsrc_info("DO NOT CONTINUOUS AF when NV12 or SN12 format");
+ return CAMERASRC_SUCCESS;
+ }
+ break;
+ case CAMERASRC_AF_MODE_TOUCH_AUTO:
+ mode = V4L2_FOCUS_AUTO_RECTANGLE;
+ camsrc_info("ON AUTOFOCUSING...BY TOUCH AUTO");
+ break;
+ case CAMERASRC_AF_MODE_PAN:
+ camsrc_warning("PAN MODE focusing is not supported.");
+ default:
+ camsrc_warning("Unsupported AF mode[%d]", handle->cur_af_mode );
+ return CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ }
+
+ /* MACRO is prior than other setting. FIXME */
+ if (handle->cur_af_range == CAMERASRC_AF_RANGE_MACRO) {
+ mode = V4L2_FOCUS_AUTO_MACRO;
+ camsrc_info("ON AUTOFOCUSING...BY MACRO");
+ }
+
+ SET_CTRL_VAL(ctrl_id, mode);
+
+ /* Start AF if continuous mode and preview is running */
+ if (mode == V4L2_FOCUS_AUTO_CONTINUOUS &&
+ handle->cur_state >= CAMERASRC_STATE_PREVIEW) {
+ _camerasrc_start_autofocusing(handle);
+ }
+
+ return CAMERASRC_SUCCESS;
+}
+
+static void __CAMERASRC_FUJITSU_GET_AF_CTRL_VAL(camerasrc_handle_t* handle, int* status)
+{
+ int err = 0;
+
+ if (af_retry_cnt >= (int)CAMERASRC_AF_TOTALTIME/CAMERASRC_AF_INTERVAL) {
+ *status = CAMERASRC_SENSOR_AF_STATUS_FAILED;
+ af_retry_cnt = 0;
+ return;
+ } else {
+ af_retry_cnt++;
+ camsrc_info("retry count = %d", af_retry_cnt);
+ }
+
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 1, err);
+ switch (err) {
+ case 0:
+ camsrc_info("Succeeded");
+ *status = CAMERASRC_SENSOR_AF_STATUS_FOCUSED;
+ af_retry_cnt = 0;
+ break;
+ case EBUSY:
+ camsrc_info("Busy");
+ *status = CAMERASRC_SENSOR_AF_STATUS_ONGOING;
+ break;
+ default:
+ camsrc_info("Failed");
+ *status = CAMERASRC_SENSOR_AF_STATUS_FAILED;
+ af_retry_cnt = 0;
+ break;
+ }
+
+ return;
+}
+
+static void* _camerasrc_run_autofocusing(camerasrc_handle_t *handle)
+{
+ int err = 0;
+ int sensor_status = 0;
+
+ camsrc_info("enter");
+
+ while(1) {
+ AF_MUT_LOCK(handle);
+ switch (handle->af_cmd) {
+ case CAMERASRC_AUTO_FOCUS_CMD_START:
+ {
+ camsrc_info("AF CMD:START");
+ __CAMERASRC_FUJITSU_GET_AF_CTRL_VAL(handle, &sensor_status);
+
+ switch (sensor_status) {
+ case CAMERASRC_SENSOR_AF_STATUS_ONGOING:
+ camsrc_info("FOCUSING. IN PROGRESS...");
+ handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_ONGOING;
+ break;
+ case CAMERASRC_SENSOR_AF_STATUS_FOCUSED: /* focus operation success. Go to Null. */
+ camsrc_info("FOCUSED. stop autofocusing...");
+
+ handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED;
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL;
+
+ CAMERASRC_SET_STATE(handle, CAMERASRC_STATE_PREVIEW);
+
+ if (handle->af_cb != NULL) {
+ if (handle->af_usr_data != NULL) {
+ handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED, handle->af_usr_data);
+ } else {
+ handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FOCUSED, NULL);
+ }
+ }
+
+ AF_MUT_UNLOCK(handle);
+ continue;
+ case CAMERASRC_SENSOR_AF_STATUS_FAILED: /* focus operation failed. Set stop and go to NULL. */
+ camsrc_info("FOCUSING FAILED");
+
+ if (handle->cur_af_mode != CAMERASRC_AF_MODE_CONTINUOUS ) {
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err);
+ camsrc_info("Stopping AF done. err = %d", err);
+ }
+
+ handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED;
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL;
+
+ CAMERASRC_SET_STATE(handle, CAMERASRC_STATE_PREVIEW);
+
+ if (handle->af_cb != NULL) {
+ if(handle->af_usr_data != NULL) {
+ handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FAILED, handle->af_usr_data);
+ } else {
+ handle->af_cb(handle, CAMERASRC_AUTO_FOCUS_RESULT_FAILED, NULL);
+ }
+ }
+
+ AF_MUT_UNLOCK(handle);
+ continue;
+ default:
+ camsrc_error("Unrecognizable status");
+ break;
+ }
+ break;
+ }
+ case CAMERASRC_AUTO_FOCUS_CMD_STOP:
+ {
+ camsrc_info("AF CMD:STOP");
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err);
+ handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED;
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL;
+ camsrc_info("Stopping AF done. err = %d", err);
+ AF_MUT_UNLOCK(handle);
+ continue;
+ }
+ case CAMERASRC_AUTO_FOCUS_CMD_KILL:
+ {
+ camsrc_info("AF CMD:KILL");
+
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err);
+ camsrc_info("Stopping AF done. err = %d", err);
+
+ handle->af_status = CAMERASRC_AUTO_FOCUS_STATUS_RELEASED;
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_NULL;
+
+ AF_MUT_UNLOCK(handle);
+ goto OUT_OF_LOOP;
+ }
+ case CAMERASRC_AUTO_FOCUS_CMD_NULL:
+ default:
+ {
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+ camsrc_info("AF CMD:NULL....");
+ err = pthread_cond_wait(&handle->af_wait_cond, &handle->af_mutex);
+ if (err) {
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_error("AF CMD pthread_cond_wait - err:(%s)", err_msg);
+ }
+
+ af_retry_cnt = 0;
+
+ /* Start AF delay for AE */
+ if (handle->af_cmd == CAMERASRC_AUTO_FOCUS_CMD_START) {
+ struct timeval cur_time;
+ int sec = 0;
+ int usec = 0;
+ int diff = 0; /* msec */
+ int sleep_time = 0; /* usec */
+
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err);
+
+ camsrc_info("Check set AF area Time(Delay:%d)", CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA);
+
+ if (handle->set_af_area_time.tv_sec != 0) {
+ gettimeofday(&cur_time, NULL);
+ sec = cur_time.tv_sec - handle->set_af_area_time.tv_sec;
+ usec = cur_time.tv_usec - handle->set_af_area_time.tv_usec;
+
+ camsrc_info("diff sec:%d, usec:%d", sec, usec);
+ diff = (sec * 1000) + (usec / 1000);
+
+ /* Skip sleep if diff is less than zero or greater than minimum exposure time */
+ if (diff < 0 || diff > CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA) {
+ camsrc_info("no need to sleep(diff: %d ms)", diff);
+ } else {
+ sleep_time = (CAMERASRC_AF_DELAY_AFTER_SET_AF_AREA - diff) * 1000;
+ camsrc_info("usleep(%d)", sleep_time);
+ usleep(sleep_time);
+ }
+ }
+ }
+
+ AF_MUT_UNLOCK(handle);
+ continue;
+ }
+ }
+
+ AF_MUT_UNLOCK(handle);
+ usleep(CAMERASRC_AF_INTERVAL);
+ }
+
+OUT_OF_LOOP:
+ camsrc_info("AF thread is finished.");
+ return NULL;
+}
+
+static int _camerasrc_start_autofocusing(camerasrc_handle_t *handle)
+{
+ int err;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+ camsrc_info("enter");
+
+ AF_MUT_LOCK(handle);
+
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_START;
+ err = pthread_cond_signal(&handle->af_wait_cond);
+ if (err) {
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_info("AF wait cond err(%s)", err_msg);
+ }
+
+ AF_MUT_UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+}
+
+static int _camerasrc_stop_autofocusing(camerasrc_handle_t *handle)
+{
+ int err;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+
+ camsrc_info("enter");
+
+ AF_MUT_LOCK(handle);
+
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_STOP;
+ err = pthread_cond_signal(&handle->af_wait_cond);
+ if (err) {
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_info("AF wait cond err(%s)", err_msg);
+ }
+
+ AF_MUT_UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+}
+
+static int _camerasrc_destroy_autofocusing(camerasrc_handle_t *handle)
+{
+ int err;
+ char err_msg[CAMERASRC_ERRMSG_MAX_LEN] = {'\0',};
+ camsrc_info("enter");
+
+ AF_MUT_LOCK(handle);
+
+ handle->af_cmd = CAMERASRC_AUTO_FOCUS_CMD_KILL;
+ err = pthread_cond_signal(&handle->af_wait_cond);
+ if (err) {
+ strerror_r(err, err_msg, CAMERASRC_ERRMSG_MAX_LEN);
+ camsrc_info("AF wait cond err(%s)", err_msg);
+ }
+
+ AF_MUT_UNLOCK(handle);
+
+ return CAMERASRC_SUCCESS;
+}
+
+static int _camerasrc_release_autofocusing(camerasrc_handle_t *handle)
+{
+ int err;
+ camsrc_info("enter");
+
+ SET_CTRL_VAL_ERR(V4L2_CID_CAMERA_SET_AUTO_FOCUS, 0, err);
+
+ return CAMERASRC_SUCCESS;
+}
+
+static int _camerasrc_copy_frame(camerasrc_handle_t *handle, camerasrc_buffer_t *src_buffer, camerasrc_buffer_t *dst_buffer, int isThumbnail)
+{
+ if (handle == NULL || src_buffer == NULL || dst_buffer == NULL) {
+ camsrc_error("handle[%p], src_buffer[%p], dst_buffer[%p]",
+ handle, src_buffer, dst_buffer);
+ return CAMERASRC_ERR_NULL_POINTER;
+ }
+
+ if (src_buffer->start == NULL || dst_buffer->start == NULL) {
+ camsrc_error("src_buffer->start[%p], dst_buffer->start[%p]",
+ src_buffer->start, dst_buffer->start);
+ return CAMERASRC_ERR_NULL_POINTER;
+ }
+
+ if (handle->format.colorspace == CAMERASRC_COL_RAW) {
+ int cpy_len;
+
+ if (handle->format.pix_format == CAMERASRC_PIX_YUV422P ||
+ handle->format.pix_format == CAMERASRC_PIX_YUY2 ||
+ handle->format.pix_format == CAMERASRC_PIX_UYVY) {
+ cpy_len = (YUV422_SIZE(handle)>=src_buffer->length)?src_buffer->length:YUV422_SIZE(handle);
+ } else if (handle->format.pix_format == CAMERASRC_PIX_YUV420P ||
+ handle->format.pix_format == CAMERASRC_PIX_YUV420 ||
+ handle->format.pix_format == CAMERASRC_PIX_NV12) {
+ cpy_len = (YUV420_SIZE(handle)>=src_buffer->length)?src_buffer->length:YUV420_SIZE(handle);
+ } else {
+ camsrc_error("UNSUPPORTED format [%x]", handle->format.pix_format );
+ return CAMERASRC_ERR_INVALID_FORMAT;
+ }
+
+#if defined (USE_FRAME_COPY_BOUNDARY_CHECK)
+ camsrc_info("Boundary check %p ~ %p ... [length = %d] ", dst_buffer->start, dst_buffer->start+cpy_len, cpy_len);
+ memset(dst_buffer->start, 0, cpy_len);
+ camsrc_info("Boundary check OK");
+#endif
+
+ camsrc_info("RAW frame dequeing...");
+ dst_buffer->length = cpy_len;
+
+ if (handle->format.pix_format == CAMERASRC_PIX_SN12) {
+ camsrc_error("Can't copy the frame with SN12 option");
+ return CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ } else if (handle->format.pix_format == CAMERASRC_PIX_ST12) {
+ camsrc_error("Can't copy the frame with ST12 option");
+ return CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ }
+
+ camsrc_error("format[%d] copy occured. copy len = %d", handle->format.pix_format, cpy_len);
+ memcpy(dst_buffer->start, src_buffer->start, cpy_len );
+ } else if (handle->format.colorspace == CAMERASRC_COL_JPEG) {
+#if defined (USE_FRAME_COPY_BOUNDARY_CHECK)
+ camsrc_info("Boundary check %p ~ %p ...", dst_buffer->start, dst_buffer->start+src_buffer->length);
+ memset(dst_buffer->start, 0, src_buffer->length);
+ camsrc_info("Boundary check OK");
+#endif
+
+ if (!isThumbnail) {
+ if (src_buffer->length <= 0) {
+ camsrc_error("length[%d] is too small", src_buffer->length );
+ return CAMERASRC_ERR_INVALID_VALUE;
+ }
+
+ dst_buffer->length = src_buffer->length;
+ camsrc_info("JPEG main frame copy... img length = %d", dst_buffer->length);
+ memcpy(dst_buffer->start, src_buffer->start, dst_buffer->length);
+ camsrc_info("JPEG main frame copy done.");
+ } else {
+ if (handle->format.pix_format == CAMERASRC_PIX_RGGB8) {
+ /* JPEG + JPEG */
+ if (src_buffer->length <= 0) {
+ camsrc_error("length[%d] is too small", src_buffer->length );
+ return CAMERASRC_ERR_INVALID_VALUE;
+ }
+
+ dst_buffer->length = src_buffer->length;
+ camsrc_info("JPEG thm frame(JPEG) copy... img length = %d", dst_buffer->length);
+ memcpy(dst_buffer->start, src_buffer->start, dst_buffer->length);
+ camsrc_info("JPEG thm frame(JPEG) copy done.");
+ } else if (handle->format.pix_format == CAMERASRC_PIX_RGGB10) {
+ /* JPEG + YUV */
+ dst_buffer->length = CAMERASRC_YUV_THMBNL_SIZE;
+ camsrc_info("JPEG thm frame(YUV) copy... img length = %d", CAMERASRC_YUV_THMBNL_SIZE);
+ memcpy(dst_buffer->start, src_buffer->start, CAMERASRC_YUV_THMBNL_SIZE);
+ camsrc_info("JPEG thm frame(YUV) copy done.");
+ } else {
+ camsrc_info("Unknown format [%d]", handle->format.pix_format );
+ return CAMERASRC_ERR_INVALID_FORMAT;
+ }
+ }
+ }
+
+ return CAMERASRC_SUCCESS;
+}
+
+
+static int _camerasrc_set_thumbnail_size(camerasrc_handle_t *handle)
+{
+ camsrc_info("enter");
+
+ return CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+}
+
+static int _camerasrc_start_facedetection (camerasrc_handle_t *handle)
+{
+ camsrc_info("enter");
+ camsrc_info("FACE DETECTION START!");
+ SET_CTRL_VAL(V4L2_CID_FACE_DETECTION, CAM_FACE_DETECTION_ON);
+ camsrc_info("leave");
+ return CAMERASRC_SUCCESS;
+}
+
+
+static int _camerasrc_stop_facedetection (camerasrc_handle_t *handle)
+{
+ camsrc_info("enter");
+ camsrc_info("FACE DETECTION STOP!");
+ SET_CTRL_VAL(V4L2_CID_FACE_DETECTION, CAM_FACE_DETECTION_OFF);
+ camsrc_info("leave");
+ return CAMERASRC_SUCCESS;
+}
+
+
+static int _camerasrc_check_emp_shock(camerasrc_handle_t *handle, int *check_val)
+{
+ camsrc_info("enter");
+ int ret_value = 0;
+
+ GET_CTRL_VAL(V4L2_CID_ESD_INT, ret_value);
+ *check_val = ret_value;
+
+ camsrc_info("leave");
+ return CAMERASRC_SUCCESS;
+}
+
+
+static int _camerasrc_get_frame_data(camerasrc_handle_t *handle, camerasrc_frame_data_t *data)
+{
+ /*camsrc_info("enter");*/
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control control;
+
+ /* Get Y physical address */
+ /*camsrc_info("[VIDIOC_G_CTRL] << [V4L2_CID_PADDR_Y] request with value");*/
+ control.id = V4L2_CID_PADDR_Y;
+ control.value = data->index;
+ err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control);
+ if (err != CAMERASRC_SUCCESS) {
+ return err;
+ }
+
+ data->phyAddrY = control.value;
+
+ /* Get CbCr physical address */
+ /*camsrc_info("[VIDIOC_G_CTRL] << [V4L2_CID_PADDR_CBCR] request with value");*/
+ control.id = V4L2_CID_PADDR_CBCR;
+ control.value = data->index;
+ err = _camerasrc_ioctl(handle, VIDIOC_S_CTRL, &control);
+ if (err != CAMERASRC_SUCCESS) {
+ return err;
+ }
+
+ data->phyAddrCbCr = control.value;
+
+ /* Distance between Y ptr and CbCr ptr of virtual address is same with that of Physical one. */
+ data->virAddrY = (unsigned int)handle->buffer[data->index].start;
+ data->virAddrCbCr = data->virAddrY + (data->phyAddrCbCr - data->phyAddrY);
+
+ /*camsrc_info("virAddrY(%p), virAddrCbCr(%p)", data->virAddrY, data->virAddrCbCr);*/
+
+ return CAMERASRC_SUCCESS;
+}
+
+
+static void _dump_exif_info(camerasrc_exif_t *exif_struct)
+{
+ camsrc_info("== Dynamic value ==");
+ camsrc_info("unsigned int exposure_time_numerator = %d", exif_struct->exposure_time_numerator);
+ camsrc_info("unsigned int exposure_time_denominator = %d", exif_struct->exposure_time_denominator);
+ camsrc_info("int shutter_speed_numerator = %d", exif_struct->shutter_speed_numerator);
+ camsrc_info("int shutter_speed_denominator = %d", exif_struct->shutter_speed_denominator);
+ camsrc_info("int brigtness_numerator = %d", exif_struct->brigtness_numerator);
+ camsrc_info("int brightness_denominator = %d", exif_struct->brightness_denominator);
+ camsrc_info("unsigned short int iso = %d", exif_struct->iso);
+ camsrc_info("unsigned short int flash = %d", exif_struct->flash);
+ camsrc_info("int metering_mode = %d", exif_struct->metering_mode);
+ camsrc_info("int exif_image_width = %d", exif_struct->exif_image_width);
+ camsrc_info("int exif_image_height = %d", exif_struct->exif_image_height);
+ camsrc_info("int exposure_bias_in_APEX = %d", exif_struct->exposure_bias_in_APEX);
+ camsrc_info("int software_used = %d", exif_struct->software_used);
+ camsrc_info("int focal_len_numerator = %d", exif_struct->focal_len_numerator);
+ camsrc_info("int focal_len_denominator = %d", exif_struct->focal_len_denominator);
+ camsrc_info("int aperture_f_num_numerator = %d", exif_struct->aperture_f_num_numerator);
+ camsrc_info("int aperture_f_num_denominator = %d", exif_struct->aperture_f_num_denominator);
+ camsrc_info("int aperture_in_APEX = %d", exif_struct->aperture_in_APEX);
+ camsrc_info("int max_lens_aperture_in_APEX = %d", exif_struct->max_lens_aperture_in_APEX);
+
+ camsrc_info("== Fixed value ==");
+ camsrc_info("int component_configuration = %x", exif_struct->component_configuration);
+ camsrc_info("int colorspace = %d", exif_struct->colorspace);
+
+ return;
+}
+
+
+static int _camerasrc_get_exif_info (camerasrc_handle_t *handle, camerasrc_exif_t *exif_struct)
+{
+ int photometry_mode = V4L2_PHOTOMETRY_MULTISEG;
+
+ if (exif_struct == NULL) {
+ return CAMERASRC_ERR_INVALID_PARAMETER;
+ }
+
+ /** Dynamic value **/
+
+ /* exposure time */
+ GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_EXPTIME, exif_struct->exposure_time_numerator);
+ exif_struct->exposure_time_denominator = 1;
+
+ /* shutter speed */
+ GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_TV, exif_struct->shutter_speed_numerator);
+ exif_struct->shutter_speed_denominator = 1;
+
+ /* brightness */
+ GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_BV, exif_struct->brigtness_numerator);
+ exif_struct->brightness_denominator = 1;
+
+ /* iso */
+ GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_ISO, exif_struct->iso);
+ ISO_APPROXIMATE_VALUE(exif_struct->iso, exif_struct->iso);
+
+ /* flash */
+ GET_CTRL_VAL(V4L2_CID_CAMERA_EXIF_FLASH, exif_struct->flash);
+
+ /* image size */
+ exif_struct->exif_image_width = handle->format.img_size.dim.width;
+ exif_struct->exif_image_height = handle->format.img_size.dim.height;
+
+ /*FIXME focal length - Set fixed value at gst_camerasrc_control_get_exif_info function */
+ exif_struct->focal_len_numerator = 1;
+ exif_struct->focal_len_denominator = 1;
+
+ /*FIXME f number - Set fixed value at gst_camerasrc_control_get_exif_info function */
+ exif_struct->aperture_f_num_numerator = 1;
+ exif_struct->aperture_f_num_denominator = 1;
+
+ /* FIXME APEX */
+ exif_struct->aperture_in_APEX \
+ = CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(exif_struct->aperture_f_num_numerator, exif_struct->aperture_f_num_denominator);
+ exif_struct->max_lens_aperture_in_APEX = 1;
+ /*= CAMERASRC_EXIF_APERTURE_VALUE_IN_APEX(exif_info.max_aperture_f_num_numerator, exif_info.max_aperture_f_num_denominator);*/
+ exif_struct->exposure_bias_in_APEX = exif_struct->aperture_in_APEX \
+ + CAMERASRC_EXIF_SHUTTERSPEED_VALUE_IN_APEX(exif_struct->exposure_time_numerator, exif_struct->exposure_time_denominator);
+
+ /* Get the value using CID */
+ /* Not implemented yet
+ GET_CTRL_VAL(V4L2_CID_FW_VERSION, exif_struct->software_used);
+ */
+ GET_CTRL_VAL(V4L2_CID_PHOTOMETRY, photometry_mode);
+ PHOTOMETRY_MODE_TO_METERING_MODE(photometry_mode, exif_struct->metering_mode);
+
+ /** Fixed value **/
+ exif_struct->component_configuration = _CAMERASRC_EXIF_COMP_CONF;
+ exif_struct->colorspace = _CAMERASRC_EXIF_COLORSPACE;
+
+ _dump_exif_info(exif_struct);
+
+ return CAMERASRC_SUCCESS;
+}
+
+static int fd_on = 0;
+
+static int _camerasrc_set_cmd(camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value)
+{
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_jpegcompression comp_arg;
+
+ switch (cmd) {
+ case _CAMERASRC_CMD_STROBE_MODE:
+ {
+ camerasrc_strobe_mode_t *mode = (camerasrc_strobe_mode_t*)value;
+
+ camsrc_info("[_CAMERASRC_CMD_STROBE_MODE] cmd set value %d", *mode );
+
+ SET_CTRL_VAL(V4L2_CID_CAMERA_FLASH_MODE, *mode);
+ }
+ break;
+ case _CAMERASRC_CMD_FACEDETECTION:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_recognition recog;
+
+ camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] cmd set");
+ if (((int)value) == _CAMERASRC_FACEDETECTION_START) {
+ camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] start");
+ recog.mode = V4L2_RECOGNITION_MODE_ON;
+ recog.pattern = V4L2_RECOG_PATTERN_FACE;
+ recog.obj_num = 10;
+ /*recog.detect_idx = 0;*/
+ recog.action= V4L2_RECOGNITION_ACTION_NONE;
+ fd_on = 1;
+ } else if (((int)value) == _CAMERASRC_FACEDETECTION_STOP) {
+ camsrc_error("[_CAMERASRC_CMD_FACEDETECTION] stop");
+ recog.mode = V4L2_RECOGNITION_MODE_OFF;
+ recog.pattern = V4L2_RECOG_PATTERN_FACE;
+ recog.obj_num = 10;
+ /*recog.detect_idx = 0;*/
+ recog.action= V4L2_RECOGNITION_ACTION_NONE;
+ fd_on = 0;
+ } else {
+ camsrc_error("[_CAMERASRC_CMD_FACEDETECTION] not support cmd");
+ }
+
+ err = _camerasrc_ioctl(handle, VIDIOC_S_RECOGNITION, &recog);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ }
+ break;
+ case _CAMERASRC_CMD_SHUTTER_SPEED:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_SHUTTER_SPEED] cmd set");
+ break;
+ case _CAMERASRC_CMD_JPEG_LENGTH:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_JPEG_LENGTH] cmd set");
+ break;
+ case _CAMERASRC_CMD_JPEG_THMBNL_LENGTH:
+ camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_LENGTH] cmd set");
+ err = _camerasrc_set_thumbnail_size(handle);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ break;
+ case _CAMERASRC_CMD_EXPOSURE_VALUE:
+ camsrc_info("[_CAMERASRC_CMD_EXPOSURE_VALUE] cmd set");
+ /* WRITEME */
+ break;
+ case _CAMERASRC_CMD_ESD_CHECK:
+ camsrc_info("[_CAMERASRC_CMD_ESD_CHECK] cmd set");
+ /* WRITEME */
+ break;
+ case _CAMERASRC_CMD_CTRL:
+ camsrc_info("[_CAMERASRC_CMD_CTRL] cmd set");
+ SET_CTRL_VAL(_CAMERASRC_GET_CID(((_camerasrc_ctrl_t *) value)->cid, handle->cur_dev_id), ((_camerasrc_ctrl_t *) value)->value);
+ break;
+ case _CAMERASRC_CMD_SUPPORT_EMBED_EXIF:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_SUPPORT_EMBED_EXIF] cmd set");
+ break;
+ case _CAMERASRC_CMD_SUPPORT_JPEG_ENCODING:
+ camsrc_warning("[_CAMERASRC_CMD_SUPPORT_JPEG_ENCODING] cmd set isn't supported");
+ break;
+ case _CAMERASRC_CMD_AF_CONTROL:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_AF_CONTROL] cmd set(value=%d)", value);
+
+ /* FIXME : Please fix whole AF implementation!!! */
+ switch ((int)value) {
+ case _CAMERASRC_AF_START:
+ _camerasrc_start_autofocusing(handle);
+ break;
+ case _CAMERASRC_AF_STOP:
+ _camerasrc_stop_autofocusing(handle);
+ break;
+ case _CAMERASRC_AF_DESTROY:
+ _camerasrc_destroy_autofocusing(handle);
+ break;
+ case _CAMERASRC_AF_RELEASE:
+ case _CAMERASRC_AF_INIT:
+ default:
+ _camerasrc_init_autofocusing_mode(handle);
+ break;
+ }
+ break;
+ case _CAMERASRC_CMD_AF_AREA:
+ {
+ camerasrc_rect_t *rect = (camerasrc_rect_t *)value;
+
+ camsrc_info("[_CAMERASRC_CMD_AF_AREA] cmd set (%d,%d,%dx%d)",
+ rect->x, rect->y, rect->width, rect->height);
+
+ SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT, rect->x);
+ SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP, rect->y);
+ SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH, 0);/*rect->width); Not supported */
+ SET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT, 0);/*rect->height); Not supported */
+
+ if (gettimeofday(&handle->set_af_area_time, NULL) == 0) {
+ camsrc_info("[_CAMERASRC_CMD_AF_AREA] Get Time Success" );
+ } else {
+ handle->set_af_area_time.tv_sec = 0;
+ handle->set_af_area_time.tv_usec = 0;
+ camsrc_warning("[_CAMERASRC_CMD_AF_AREA] Get Time Failed" );
+ }
+ break;
+ }
+ case _CAMERASRC_CMD_FRAME_DATA:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_FRAME_DATA] cmd set");
+ break;
+ case _CAMERASRC_CMD_EXIF_INFO:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_EXIF_INFO] cmd set");
+ break;
+ case _CAMERASRC_CMD_CHECK_ESD:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_CHECK_ESD] cmd set");
+ break;
+ case _CAMERASRC_CMD_JPEG_COMPRESS_RATIO:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_JPEG_COMPRESS_RATIO] cmd set, val = %d", (int)(*((unsigned int*) value)));
+ if (handle->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) {
+ comp_arg.quality = (int)(*((unsigned int*) value));
+ err = _camerasrc_ioctl(handle, VIDIOC_S_JPEGCOMP, &comp_arg);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ } else if (handle->cur_dev_id == CAMERASRC_DEV_ID_SECONDARY) {
+ err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ goto ERROR;
+ }
+ break;
+ case _CAMERASRC_CMD_ROTATION:
+ {
+ int *rotate = (int *)value;
+ camsrc_info("[_CAMERASRC_CMD_ROTATION] cmd set : %d", *rotate);
+ SET_CTRL_VAL(V4L2_CID_ROTATION, (int)*rotate);
+ }
+ break;
+ case _CAMERASRC_CMD_SENSOR_MODE:
+ {
+ camerasrc_sensor_mode_t *mode = (camerasrc_sensor_mode_t *)value;
+ camsrc_info("[_CAMERASRC_CMD_SENSOR_MODE] cmd set : %d", *mode);
+ SET_CTRL_VAL(V4L2_CID_CAMERA_SENSOR_MODE, (int)*mode);
+ }
+ break;
+ case _CAMERASRC_CMD_VFLIP:
+ {
+ int *vflip = (int *)value;
+ camsrc_info("[_CAMERASRC_CMD_VFLIP] cmd set : %d", *vflip);
+ SET_CTRL_VAL(V4L2_CID_VFLIP, (int)*vflip);
+ }
+ break;
+ case _CAMERASRC_CMD_HFLIP:
+ {
+ int *hflip = (int *)value;
+ camsrc_info("[_CAMERASRC_CMD_HFLIP] cmd set : %d", *hflip);
+ SET_CTRL_VAL(V4L2_CID_HFLIP, (int)*hflip);
+ }
+ break;
+ default:
+ camsrc_error("[_CAMERASRC_CMD_UNKNOWN] cmd set");
+ err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ goto ERROR;
+ }
+
+ return CAMERASRC_SUCCESS;
+
+ERROR:
+ camsrc_error("cmd execution error occured");
+
+ return err;
+}
+
+static int _camerasrc_get_cmd(camerasrc_handle_t *handle, _camsrc_cmd_t cmd, void *value)
+{
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_jpegcompression comp_arg;
+
+ if (!value) {
+ camsrc_error("value is NULL");
+ return CAMERASRC_ERR_NULL_POINTER;
+ }
+
+ switch (cmd) {
+ case _CAMERASRC_CMD_SUPPORT_EMBED_EXIF:
+ camsrc_info("[_CAMERASRC_CMD_SUPPORT_EMBED_EXIF] cmd get");
+ *((int*)value) = _CAMERASRC_CMD_SUPPORT_EMBED_EXIF_DEF;
+ break;
+ case _CAMERASRC_CMD_SUPPORT_JPEG_ENCODING:
+ camsrc_info("[_CAMERASRC_CMD_SUPPORT_JPEG_ENCODING] cmd get(cur_dev_id=%d)", handle->cur_dev_id);
+ if (handle->cur_dev_id == CAMERASRC_DEV_ID_PRIMARY) {
+ *((int*)value) = 1;
+ } else {
+ *((int*)value) = 0;
+ }
+ break;
+ case _CAMERASRC_CMD_STROBE_MODE:
+ {
+ camerasrc_strobe_mode_t mode;
+
+ GET_CTRL_VAL(V4L2_CID_CAMERA_FLASH_MODE, mode);
+ *((camerasrc_strobe_mode_t*)value) = mode;
+
+ camsrc_info("[_CAMERASRC_CMD_STROBE_MODE] cmd get - %d", mode);
+ }
+ break;
+ case _CAMERASRC_CMD_FACEDETECTION:
+ camsrc_info("[_CAMERASRC_CMD_FACEDETECTION] cmd get - %d", fd_on);
+ *(int *)value = fd_on;
+ break;
+ case _CAMERASRC_CMD_SHUTTER_SPEED:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_SHUTTER_SPEED] cmd get");
+ break;
+ case _CAMERASRC_CMD_JPEG_LENGTH:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control ctrl;
+
+ ctrl.id = V4L2_CID_CAM_JPEG_MAIN_SIZE;
+ err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl );
+ if (err != CAMERASRC_SUCCESS) {
+ *((int*)value) = 0;
+ goto ERROR;
+ }
+
+ *((int*)value) = ctrl.value;
+ camsrc_info("[_CAMERASRC_CMD_JPEG_LENGTH] cmd get");
+ break;
+ }
+ case _CAMERASRC_CMD_JPEG_THMBNL_LENGTH:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control ctrl;
+
+ ctrl.id = V4L2_CID_CAM_JPEG_THUMB_SIZE;
+ err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl );
+ if (err != CAMERASRC_SUCCESS) {
+ *((int*)value) = 0;
+ goto ERROR;
+ }
+
+ *((int*)value) = ctrl.value;
+ camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_LENGTH] cmd get : %d", *((int*)value));
+ break;
+ }
+ case _CAMERASRC_CMD_JPEG_THMBNL_OFFSET:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control ctrl;
+ ctrl.id = V4L2_CID_CAM_JPEG_THUMB_OFFSET;
+
+ err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl );
+ if(err != CAMERASRC_SUCCESS)
+ {
+ *((int*)value) = 0;
+ goto ERROR;
+ }
+
+ *((int*)value) = ctrl.value;
+ camsrc_info("[_CAMERASRC_CMD_JPEG_THMBNL_OFFSET] cmd get : %x", *((int*)value));
+ break;
+ }
+ case _CAMERASRC_CMD_JPEG_SCRNL_LENGTH:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control ctrl;
+ ctrl.id = V4L2_CID_CAM_JPEG_POSTVIEW_SIZE;
+
+ err = _camerasrc_ioctl(handle, VIDIOC_G_CTRL, &ctrl);
+ if (err != CAMERASRC_SUCCESS) {
+ *((int*)value) = 0;
+ goto ERROR;
+ }
+
+ *((int*)value) = ctrl.value;
+ camsrc_info("[_CAMERASRC_CMD_JPEG_SCRNL_LENGTH] cmd get : %x", *((int*)value));
+ break;
+ }
+ case _CAMERASRC_CMD_JPEG_SCRNL_OFFSET:
+ {
+ int err = CAMERASRC_ERR_UNKNOWN;
+ struct v4l2_control ctrl;
+ ctrl.id = V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET;
+
+ err = _camerasrc_ioctl( handle, VIDIOC_G_CTRL, &ctrl );
+ if (err != CAMERASRC_SUCCESS) {
+ *((int*)value) = 0;
+ goto ERROR;
+ }
+
+ *((int*)value) = ctrl.value;
+ camsrc_info("[_CAMERASRC_CMD_JPEG_SCRNL_OFFSET] cmd get : %x", *((int*)value));
+ break;
+ }
+ case _CAMERASRC_CMD_EXPOSURE_VALUE:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_EXPOSURE_VALUE] cmd get");
+ break;
+ case _CAMERASRC_CMD_ESD_CHECK:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_ESD_CHECK] cmd get");
+ break;
+ case _CAMERASRC_CMD_CTRL:
+ camsrc_info("[_CAMERASRC_CMD_CTRL] cmd get");
+ GET_CTRL_VAL(_CAMERASRC_GET_CID(((_camerasrc_ctrl_t *) value)->cid, handle->cur_dev_id), ((_camerasrc_ctrl_t *) value)->value);
+ break;
+ case _CAMERASRC_CMD_AF_CONTROL:
+ /* WRITEME */
+ camsrc_info("[_CAMERASRC_CMD_AF_CONTROL] cmd get");
+ break;
+ case _CAMERASRC_CMD_AF_AREA:
+ {
+ camerasrc_rect_t* rect = (camerasrc_rect_t*)value;
+
+ GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT, rect->x);
+ GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP, rect->y);
+ GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH, rect->width);
+ GET_CTRL_VAL(V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT, rect->height);
+
+ camsrc_info("[_CAMERASRC_CMD_AF_AREA] cmd get (%d,%d,%dx%d)",
+ rect->x, rect->y, rect->width, rect->height);
+ break;
+ }
+ case _CAMERASRC_CMD_FRAME_DATA:
+ /* WRITEME */
+ /*camsrc_info("[_CAMERASRC_CMD_FRAME_DATA] cmd get");*/
+ err = _camerasrc_get_frame_data(handle, (camerasrc_frame_data_t*)value);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ break;
+ case _CAMERASRC_CMD_EXIF_INFO:
+ camsrc_info("[_CAMERASRC_CMD_EXIF_INFO] cmd get");
+ err = _camerasrc_get_exif_info (handle, (camerasrc_exif_t*)value);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ break;
+ case _CAMERASRC_CMD_CHECK_ESD:
+ camsrc_info("[_CAMERASRC_CMD_CHECK_ESD] cmd get");
+ GET_CTRL_VAL(V4L2_CID_ESD_INT, *((int *) value));
+ break;
+ case _CAMERASRC_CMD_JPEG_COMPRESS_RATIO:
+ camsrc_info("[_CAMERASRC_CMD_JPEG_COMPRESS_RATIO] cmd get");
+ err = _camerasrc_ioctl(handle, VIDIOC_G_JPEGCOMP, &comp_arg);
+ if (err != CAMERASRC_SUCCESS) {
+ goto ERROR;
+ }
+ *((unsigned int*)value) = (int)comp_arg.quality;
+ break;
+ case _CAMERASRC_CMD_ROTATION:
+ camsrc_info("[_CAMERASRC_CMD_ROTATION] cmd get");
+ GET_CTRL_VAL(V4L2_CID_ROTATION, *(int*)value);
+ break;
+ case _CAMERASRC_CMD_SENSOR_MODE:
+ camsrc_info("[_CAMERASRC_CMD_SENSOR_MODE] cmd get");
+ GET_CTRL_VAL(V4L2_CID_CAMERA_SENSOR_MODE, *(int*)value);
+ break;
+ case _CAMERASRC_CMD_VFLIP:
+ camsrc_info("[_CAMERASRC_CMD_VFLIP] cmd get");
+ GET_CTRL_VAL(V4L2_CID_VFLIP, *(int*)value);
+ break;
+ case _CAMERASRC_CMD_HFLIP:
+ camsrc_info("[_CAMERASRC_CMD_HFLIP] cmd get");
+ GET_CTRL_VAL(V4L2_CID_HFLIP, *(int*)value);
+ break;
+ default:
+ camsrc_error("[_CAMERASRC_CMD_UNKNOWN] cmd get");
+ err = CAMERASRC_ERR_DEVICE_NOT_SUPPORT;
+ goto ERROR;
+ }
+
+ return CAMERASRC_SUCCESS;
+
+ERROR:
+ camsrc_error("cmd execution error occured");
+
+ return err;
+}
+
+static const CAMERASRC_DEV_DEPENDENT_MISC_FUNC dev_misc_functions = {
+ ._ioctl = _camerasrc_ioctl,
+ ._ioctl_once = _camerasrc_ioctl_once,
+ ._run_autofocusing = _camerasrc_run_autofocusing,
+ ._skip_frame = _camerasrc_skip_frame,
+ ._copy_frame = _camerasrc_copy_frame,
+ ._set_cmd = _camerasrc_set_cmd,
+ ._get_cmd = _camerasrc_get_cmd,
+};
+
+const CAMERASRC_DEV_DEPENDENT_MISC_FUNC *dev_misc_func = &dev_misc_functions;