| /* |
| * Copyright (C) 2011 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. |
| */ |
| |
| /*! |
| * \file exynos_v4l2.c |
| * \brief source file for libv4l2 |
| * \author Jinsung Yang (jsgood.yang@samsung.com) |
| * \author Sangwoo Park (sw5771.park@samsung.com) |
| * \date 2012/01/17 |
| * |
| * <b>Revision History: </b> |
| * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n |
| * Initial version |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <errno.h> |
| #include <stdarg.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <sys/ioctl.h> |
| #include <sys/stat.h> |
| |
| #include "exynos_v4l2.h" |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "libexynosv4l2" |
| #include <utils/Log.h> |
| #include "Exynos_log.h" |
| |
| #define VIDEODEV_MINOR_MAX 63 |
| |
| //#define EXYNOS_V4L2_TRACE 0 |
| #ifdef EXYNOS_V4L2_TRACE |
| #define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) |
| #define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) |
| #else |
| #define Exynos_v4l2_In() ((void *)0) |
| #define Exynos_v4l2_Out() ((void *)0) |
| #endif |
| |
| static bool __v4l2_check_buf_type(enum v4l2_buf_type type) |
| { |
| bool supported; |
| |
| switch (type) { |
| case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
| supported = true; |
| break; |
| |
| default: |
| supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false; |
| break; |
| } |
| |
| return supported; |
| } |
| |
| static int __v4l2_open(const char *filename, int oflag, va_list ap) |
| { |
| mode_t mode = 0; |
| int fd; |
| |
| if (oflag & O_CREAT) |
| mode = va_arg(ap, int); |
| |
| fd = open(filename, oflag, mode); |
| |
| return fd; |
| } |
| |
| int exynos_v4l2_open(const char *filename, int oflag, ...) |
| { |
| va_list ap; |
| int fd; |
| |
| Exynos_v4l2_In(); |
| |
| va_start(ap, oflag); |
| fd = __v4l2_open(filename, oflag, ap); |
| va_end(ap); |
| |
| Exynos_v4l2_Out(); |
| |
| return fd; |
| } |
| |
| int exynos_v4l2_open_devname(const char *devname, int oflag, ...) |
| { |
| bool found = false; |
| int fd = -1; |
| struct stat s; |
| va_list ap; |
| FILE *stream_fd; |
| char filename[64], name[64]; |
| int minor, size, i = 0; |
| |
| Exynos_v4l2_In(); |
| |
| do { |
| if (i > VIDEODEV_MINOR_MAX) |
| break; |
| |
| /* video device node */ |
| sprintf(filename, "/dev/video%d", i++); |
| |
| /* if the node is video device */ |
| if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) && |
| ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) { |
| minor = (int)((unsigned short)(s.st_rdev & 0x3f)); |
| ALOGD("try node: %s, minor: %d", filename, minor); |
| /* open sysfs entry */ |
| sprintf(filename, "/sys/class/video4linux/video%d/name", minor); |
| stream_fd = fopen(filename, "r"); |
| if (stream_fd == NULL) { |
| ALOGE("failed to open sysfs entry for videodev"); |
| continue; /* try next */ |
| } |
| |
| /* read sysfs entry for device name */ |
| size = (int)fgets(name, sizeof(name), stream_fd); |
| fclose(stream_fd); |
| |
| /* check read size */ |
| if (size == 0) { |
| ALOGE("failed to read sysfs entry for videodev"); |
| } else { |
| /* matched */ |
| if (strncmp(name, devname, strlen(devname)) == 0) { |
| ALOGI("node found for device %s: /dev/video%d", devname, minor); |
| found = true; |
| } |
| } |
| } |
| } while (found == false); |
| |
| if (found) { |
| sprintf(filename, "/dev/video%d", minor); |
| va_start(ap, oflag); |
| fd = __v4l2_open(filename, oflag, ap); |
| va_end(ap); |
| |
| if (fd > 0) |
| ALOGI("open video device %s", filename); |
| else |
| ALOGE("failed to open video device %s", filename); |
| } else { |
| ALOGE("no video device found"); |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return fd; |
| } |
| |
| int exynos_v4l2_close(int fd) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| else |
| ret = close(fd); |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf) |
| { |
| int ret = -1; |
| struct v4l2_input input; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return NULL; |
| } |
| |
| input.index = index; |
| ret = ioctl(fd, VIDIOC_ENUMINPUT, &input); |
| if (ret) { |
| ALOGE("%s: no matching index founds", __func__); |
| return false; |
| } |
| |
| ALOGI("Name of input channel[%d] is %s", input.index, input.name); |
| |
| strcpy(input_name_buf, (const char *)input.name); |
| |
| Exynos_v4l2_Out(); |
| |
| return true; |
| } |
| |
| int exynos_v4l2_s_input(int fd, int index) |
| { |
| int ret = -1; |
| struct v4l2_input input; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| input.index = index; |
| |
| ret = ioctl(fd, VIDIOC_S_INPUT, &input); |
| if (ret){ |
| ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| bool exynos_v4l2_querycap(int fd, unsigned int need_caps) |
| { |
| struct v4l2_capability cap; |
| int ret; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return false; |
| } |
| |
| if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) && |
| !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) && |
| !(need_caps & V4L2_CAP_VIDEO_OUTPUT) && |
| !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) && |
| !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) { |
| ALOGE("%s: unsupported capabilities", __func__); |
| return false; |
| } |
| |
| memset(&cap, 0, sizeof(cap)); |
| |
| ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno)); |
| return false; |
| } |
| |
| if ((need_caps & cap.capabilities) != need_caps) { |
| ALOGE("%s: unsupported capabilities", __func__); |
| return false; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return true; |
| } |
| |
| bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt) |
| { |
| struct v4l2_fmtdesc fmtdesc; |
| int found = 0; |
| |
| Exynos_v4l2_In(); |
| |
| fmtdesc.type = type; |
| fmtdesc.index = 0; |
| |
| while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) { |
| if (fmtdesc.pixelformat == fmt) { |
| ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description); |
| found = 1; |
| break; |
| } |
| |
| fmtdesc.index++; |
| } |
| |
| if (!found) { |
| ALOGE("%s: unsupported pixel format", __func__); |
| return false; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return true; |
| } |
| |
| int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!fmt) { |
| ALOGE("%s: fmt is NULL", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(fmt->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_G_FMT, fmt); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!fmt) { |
| ALOGE("%s: fmt is NULL", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(fmt->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } else { |
| ret = ioctl(fd, request, fmt); |
| if (ret) { |
| if (request == VIDIOC_TRY_FMT) |
| ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno)); |
| else |
| ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno)); |
| |
| return ret; |
| } |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt) |
| { |
| return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt); |
| } |
| |
| int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt) |
| { |
| return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt); |
| } |
| |
| int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req) |
| { |
| int ret = -1; |
| unsigned int count; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!req) { |
| ALOGE("%s: req is NULL", __func__); |
| return ret; |
| } |
| |
| if ((req->memory != V4L2_MEMORY_MMAP) && |
| (req->memory != V4L2_MEMORY_USERPTR) && |
| (req->memory != V4L2_MEMORY_DMABUF)) { |
| ALOGE("%s: unsupported memory type", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(req->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| count = req->count; |
| |
| ret = ioctl(fd, VIDIOC_REQBUFS, req); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno)); |
| return ret; |
| } |
| |
| if (count != req->count) { |
| ALOGW("number of buffers had been changed: %d => %d", count, req->count); |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!buf) { |
| ALOGE("%s: buf is NULL", __func__); |
| return ret; |
| } |
| |
| if ((buf->memory != V4L2_MEMORY_MMAP) && |
| (buf->memory != V4L2_MEMORY_DMABUF)) { |
| ALOGE("%s: unsupported memory type", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(buf->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_QUERYBUF, buf); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!buf) { |
| ALOGE("%s: buf is NULL", __func__); |
| return ret; |
| } |
| |
| if ((buf->memory != V4L2_MEMORY_MMAP) && |
| (buf->memory != V4L2_MEMORY_USERPTR) && |
| (buf->memory != V4L2_MEMORY_DMABUF)) { |
| ALOGE("%s: unsupported memory type", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(buf->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_QBUF, buf); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!buf) { |
| ALOGE("%s: buf is NULL", __func__); |
| return ret; |
| } |
| |
| if ((buf->memory != V4L2_MEMORY_MMAP) && |
| (buf->memory != V4L2_MEMORY_USERPTR) && |
| (buf->memory != V4L2_MEMORY_DMABUF)) { |
| ALOGE("%s: unsupported memory type", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(buf->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_DQBUF, buf); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_DQBUF (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_STREAMON, &type); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_STREAMOFF, &type); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!crop) { |
| ALOGE("%s: crop is NULL", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(crop->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_CROPCAP, crop); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!crop) { |
| ALOGE("%s: crop is NULL", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(crop->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_G_CROP, crop); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (!crop) { |
| ALOGE("%s: crop is NULL", __func__); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(crop->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_S_CROP, crop); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value) |
| { |
| int ret = -1; |
| struct v4l2_control ctrl; |
| |
| Exynos_v4l2_In(); |
| |
| ctrl.id = id; |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| *value = ctrl.value; |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value) |
| { |
| int ret = -1; |
| struct v4l2_control ctrl; |
| |
| Exynos_v4l2_In(); |
| |
| ctrl.id = id; |
| ctrl.value = value; |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", errno); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(streamparm->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_G_PARM, streamparm); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (__v4l2_check_buf_type(streamparm->type) == false) { |
| ALOGE("%s: unsupported buffer type", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_S_PARM, streamparm); |
| if (ret) { |
| ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno)); |
| return ret; |
| } |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (ctrl == NULL) { |
| ALOGE("%s: ctrl is NULL", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl); |
| if (ret) |
| ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno)); |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |
| |
| int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl) |
| { |
| int ret = -1; |
| |
| Exynos_v4l2_In(); |
| |
| if (fd < 0) { |
| ALOGE("%s: invalid fd: %d", __func__, fd); |
| return ret; |
| } |
| |
| if (ctrl == NULL) { |
| ALOGE("%s: ctrl is NULL", __func__); |
| return ret; |
| } |
| |
| ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl); |
| if (ret) |
| ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno)); |
| |
| Exynos_v4l2_Out(); |
| |
| return ret; |
| } |