diff options
Diffstat (limited to 'camera/smdk4x12_v4l2.c')
-rw-r--r-- | camera/smdk4x12_v4l2.c | 739 |
1 files changed, 739 insertions, 0 deletions
diff --git a/camera/smdk4x12_v4l2.c b/camera/smdk4x12_v4l2.c new file mode 100644 index 0000000..e8b130e --- /dev/null +++ b/camera/smdk4x12_v4l2.c @@ -0,0 +1,739 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <malloc.h> +#include <poll.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include <asm/types.h> + +#define LOG_TAG "smdk4x12_v4l2" +#include <utils/Log.h> + +#include "smdk4x12_camera.h" + +int smdk4x12_v4l2_init(struct smdk4x12_camera *smdk4x12_camera) +{ + int i; + + for (i = 0; i < SMDK4x12_CAMERA_MAX_V4L2_NODES_COUNT; i++) + smdk4x12_camera->v4l2_fds[i] = -1; + + return 0; +} + +int smdk4x12_v4l2_index(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) +{ + int index; + int i; + + if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || + smdk4x12_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + if (smdk4x12_v4l2_id > smdk4x12_camera->config->v4l2_nodes_count) + return -1; + + index = -1; + for (i = 0; i < smdk4x12_camera->config->v4l2_nodes_count; i++) { + if (smdk4x12_camera->config->v4l2_nodes[i].id == smdk4x12_v4l2_id && + smdk4x12_camera->config->v4l2_nodes[i].node != NULL) { + index = i; + } + } + + return index; +} + +int smdk4x12_v4l2_fd(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) +{ + int index; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 index for id %d", __func__, smdk4x12_v4l2_id); + return -1; + } + + return smdk4x12_camera->v4l2_fds[index]; +} + +int smdk4x12_v4l2_open(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) +{ + char *node; + int index; + int fd; + + if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || + smdk4x12_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, smdk4x12_v4l2_id); + return -1; + } + + node = smdk4x12_camera->config->v4l2_nodes[index].node; + fd = open(node, O_RDWR); + if (fd < 0) { + ALOGE("%s: Unable to open v4l2 node for id %d", __func__, smdk4x12_v4l2_id); + return -1; + } + + smdk4x12_camera->v4l2_fds[index] = fd; + + return 0; +} + +void smdk4x12_v4l2_close(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) +{ + int index; + + if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || + smdk4x12_camera->config->v4l2_nodes == NULL) + return; + + index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, smdk4x12_v4l2_id); + return; + } + + if (smdk4x12_camera->v4l2_fds[index] >= 0) + close(smdk4x12_camera->v4l2_fds[index]); + + smdk4x12_camera->v4l2_fds[index] = -1; +} + +int smdk4x12_v4l2_ioctl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int request, void *data) +{ + int fd; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + fd = smdk4x12_v4l2_fd(smdk4x12_camera, smdk4x12_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, smdk4x12_v4l2_id); + return -1; + } + + return ioctl(fd, request, data); +} + +int smdk4x12_v4l2_poll(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) +{ + struct pollfd events; + int fd; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + fd = smdk4x12_v4l2_fd(smdk4x12_camera, smdk4x12_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, smdk4x12_v4l2_id); + return -1; + } + + memset(&events, 0, sizeof(events)); + events.fd = fd; + events.events = POLLIN | POLLERR; + + rc = poll(&events, 1, 1000); + if (rc < 0 || events.revents & POLLERR) + return -1; + + return rc; +} + +int smdk4x12_v4l2_qbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int type, int memory, int index, unsigned long userptr) +{ + struct v4l2_buffer buffer; + int rc; + + if (smdk4x12_camera == NULL || index < 0) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + if (userptr) + buffer.m.userptr = userptr; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QBUF, &buffer); + return rc; +} + +int smdk4x12_v4l2_qbuf_cap(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int index) +{ + return smdk4x12_v4l2_qbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index, 0); +} + +int smdk4x12_v4l2_qbuf_out(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int index, unsigned long userptr) +{ + return smdk4x12_v4l2_qbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index, userptr); +} + +int smdk4x12_v4l2_dqbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int type, int memory) +{ + struct v4l2_buffer buffer; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_DQBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.index; +} + +int smdk4x12_v4l2_dqbuf_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_dqbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP); +} + +int smdk4x12_v4l2_dqbuf_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_dqbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR); +} + +int smdk4x12_v4l2_reqbufs(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type, int memory, int count) +{ + struct v4l2_requestbuffers requestbuffers; + int rc; + + if (smdk4x12_camera == NULL || count < 0) + return -EINVAL; + + requestbuffers.type = type; + requestbuffers.count = count; + requestbuffers.memory = memory; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_REQBUFS, &requestbuffers); + if (rc < 0) + return rc; + + return requestbuffers.count; +} + +int smdk4x12_v4l2_reqbufs_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int count) +{ + return smdk4x12_v4l2_reqbufs(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, count); +} + +int smdk4x12_v4l2_reqbufs_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int count) +{ + return smdk4x12_v4l2_reqbufs(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, count); +} + +int smdk4x12_v4l2_querybuf(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type, int memory, int index) +{ + struct v4l2_buffer buffer; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QUERYBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.length; +} + +int smdk4x12_v4l2_querybuf_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int index) +{ + return smdk4x12_v4l2_querybuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index); +} + +int smdk4x12_v4l2_querybuf_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int index) +{ + return smdk4x12_v4l2_querybuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index); +} + +int smdk4x12_v4l2_querycap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int flags) +{ + struct v4l2_capability cap; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QUERYCAP, &cap); + if (rc < 0) + return rc; + + if (!(cap.capabilities & flags)) + return -1; + + return 0; +} + +int smdk4x12_v4l2_querycap_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_querycap(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_CAP_VIDEO_CAPTURE); +} + +int smdk4x12_v4l2_querycap_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_querycap(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_CAP_VIDEO_OUTPUT); +} + +int smdk4x12_v4l2_streamon(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_STREAMON, &buf_type); + return rc; +} + +int smdk4x12_v4l2_streamon_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_streamon(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int smdk4x12_v4l2_streamon_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_streamon(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int smdk4x12_v4l2_streamoff(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_STREAMOFF, &buf_type); + return rc; +} + +int smdk4x12_v4l2_streamoff_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_streamoff(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int smdk4x12_v4l2_streamoff_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id) +{ + return smdk4x12_v4l2_streamoff(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int smdk4x12_v4l2_g_fmt(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int type, int *width, int *height, int *fmt) +{ + struct v4l2_format format; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + format.type = type; + format.fmt.pix.field = V4L2_FIELD_NONE; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_FMT, &format); + if (rc < 0) + return rc; + + if (width != NULL) + *width = format.fmt.pix.width; + if (height != NULL) + *height = format.fmt.pix.height; + if (fmt != NULL) + *fmt = format.fmt.pix.pixelformat; + + return 0; +} + +int smdk4x12_v4l2_g_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int *width, int *height, int *fmt) +{ + return smdk4x12_v4l2_g_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt); +} + +int smdk4x12_v4l2_g_fmt_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int *width, int *height, int *fmt) +{ + return smdk4x12_v4l2_g_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt); +} + +int smdk4x12_v4l2_s_fmt_pix(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type, int width, int height, int fmt, int field, + int priv) +{ + struct v4l2_format format; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = type; + format.fmt.pix.width = width; + format.fmt.pix.height = height; + format.fmt.pix.pixelformat = fmt; + format.fmt.pix.field = field; + format.fmt.pix.priv = priv; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FMT, &format); + return rc; + + return 0; +} + +int smdk4x12_v4l2_s_fmt_pix_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int width, int height, int fmt, int priv) +{ + return smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int smdk4x12_v4l2_s_fmt_pix_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int width, int height, int fmt, int priv) +{ + return smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int smdk4x12_v4l2_s_fmt_win(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int left, int top, int width, int height) +{ + struct v4l2_format format; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + format.fmt.win.w.left = left; + format.fmt.win.w.top = top; + format.fmt.win.w.width = width; + format.fmt.win.w.height = height; + + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FMT, &format); + return rc; +} + +int smdk4x12_v4l2_enum_fmt(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int type, int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + fmtdesc.type = type; + fmtdesc.index = 0; + + do { + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_ENUM_FMT, &fmtdesc); + if (rc < 0) + return rc; + + if (fmtdesc.pixelformat == (unsigned int) fmt) + return 0; + + fmtdesc.index++; + } while (rc >= 0); + + return -1; +} + +int smdk4x12_v4l2_enum_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int fmt) +{ + return smdk4x12_v4l2_enum_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + fmt); +} + +int smdk4x12_v4l2_enum_fmt_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int fmt) +{ + return smdk4x12_v4l2_enum_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + fmt); +} + +int smdk4x12_v4l2_enum_input(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int id) +{ + struct v4l2_input input; + int rc; + + if (smdk4x12_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_ENUMINPUT, &input); + if (rc < 0) + return rc; + + if (input.name[0] == '\0') + return -1; + + return 0; +} + +int smdk4x12_v4l2_s_input(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int id) +{ + struct v4l2_input input; + int rc; + + if (smdk4x12_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_INPUT, &input); + return rc; +} + +int smdk4x12_v4l2_g_ext_ctrls(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, struct v4l2_ext_control *control, int count) +{ + struct v4l2_ext_controls controls; + int rc; + + if (smdk4x12_camera == NULL || control == NULL) + return -EINVAL; + + memset(&controls, 0, sizeof(controls)); + controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + controls.count = count; + controls.controls = control; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_EXT_CTRLS, &controls); + return rc; +} + +int smdk4x12_v4l2_g_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int id, int *value) +{ + struct v4l2_control control; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + control.id = id; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_CTRL, &control); + if (rc < 0) + return rc; + + if (value != NULL) + *value = control.value; + + return 0; +} + +int smdk4x12_v4l2_s_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int id, int value) +{ + struct v4l2_control control; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + control.id = id; + control.value = value; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_CTRL, &control); + if (rc < 0) + return rc; + + return control.value; +} + +int smdk4x12_v4l2_s_parm(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int type, struct v4l2_streamparm *streamparm) +{ + int rc; + + if (smdk4x12_camera == NULL || streamparm == NULL) + return -EINVAL; + + streamparm->type = type; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_PARM, streamparm); + return rc; +} + +int smdk4x12_v4l2_s_parm_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return smdk4x12_v4l2_s_parm(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + streamparm); +} + +int smdk4x12_v4l2_s_parm_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return smdk4x12_v4l2_s_parm(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + streamparm); +} + +int smdk4x12_v4l2_s_crop(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + int type, int left, int top, int width, int height) +{ + struct v4l2_crop crop; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + crop.type = type; + crop.c.left = left; + crop.c.top = top; + crop.c.width = width; + crop.c.height = height; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_CROP, &crop); + return rc; +} + +int smdk4x12_v4l2_s_crop_cap(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int left, int top, int width, int height) +{ + return smdk4x12_v4l2_s_crop(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + left, top, width, height); +} + +int smdk4x12_v4l2_s_crop_out(struct smdk4x12_camera *smdk4x12_camera, + int smdk4x12_v4l2_id, int left, int top, int width, int height) +{ + return smdk4x12_v4l2_s_crop(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + left, top, width, height); +} + +int smdk4x12_v4l2_g_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + void **base, int *width, int *height, int *fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_FBUF, &framebuffer); + if (rc < 0) + return rc; + + if (base != NULL) + *base = framebuffer.base; + if (width != NULL) + *width = framebuffer.fmt.width; + if (height != NULL) + *height = framebuffer.fmt.height; + if (fmt != NULL) + *fmt = framebuffer.fmt.pixelformat; + + return 0; +} + +int smdk4x12_v4l2_s_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, + void *base, int width, int height, int fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (smdk4x12_camera == NULL) + return -EINVAL; + + memset(&framebuffer, 0, sizeof(framebuffer)); + framebuffer.base = base; + framebuffer.fmt.width = width; + framebuffer.fmt.height = height; + framebuffer.fmt.pixelformat = fmt; + + rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FBUF, &framebuffer); + return rc; +} |