2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * \brief source file for libv4l2
20 * \author Jinsung Yang (jsgood.yang@samsung.com)
21 * \author Sangwoo Park (sw5771.park@samsung.com)
24 * <b>Revision History: </b>
25 * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
39 #include "exynos_v4l2.h"
41 //#define LOG_NDEBUG 0
42 #define LOG_TAG "libexynosv4l2"
43 #include <utils/Log.h>
44 #include "Exynos_log.h"
46 #define VIDEODEV_MINOR_MAX 69
48 //#define EXYNOS_V4L2_TRACE 0
49 #ifdef EXYNOS_V4L2_TRACE
50 #define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
51 #define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
53 #define Exynos_v4l2_In() ((void *)0)
54 #define Exynos_v4l2_Out() ((void *)0)
57 static bool __v4l2_check_buf_type(enum v4l2_buf_type type
)
62 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
63 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
64 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
65 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
66 case V4L2_BUF_TYPE_VIDEO_OVERLAY
:
71 supported
= (type
>= V4L2_BUF_TYPE_PRIVATE
) ? true : false;
78 static int __v4l2_open(const char *filename
, int oflag
, va_list ap
)
84 mode
= va_arg(ap
, int);
86 fd
= open(filename
, oflag
, mode
);
91 int exynos_v4l2_open(const char *filename
, int oflag
, ...)
99 fd
= __v4l2_open(filename
, oflag
, ap
);
107 int exynos_v4l2_open_devname(const char *devname
, int oflag
, ...)
114 char filename
[64], name
[64];
115 int minor
, size
, i
= 0;
120 if (i
> VIDEODEV_MINOR_MAX
)
123 /* video device node */
124 snprintf(filename
, sizeof(filename
), "/dev/video%d", i
++);
126 /* if the node is video device */
127 if ((lstat(filename
, &s
) == 0) && S_ISCHR(s
.st_mode
) &&
128 ((int)((unsigned short)(s
.st_rdev
) >> 8) == 81)) {
129 minor
= (int)((unsigned short)(s
.st_rdev
& 0x3f));
130 ALOGD("try node: %s, minor: %d", filename
, minor
);
131 /* open sysfs entry */
132 snprintf(filename
, sizeof(filename
), "/sys/class/video4linux/video%d/name", minor
);
133 if (S_ISLNK(s
.st_mode
)) {
134 ALOGE("symbolic link detected");
137 stream_fd
= fopen(filename
, "r");
138 if (stream_fd
== NULL
) {
139 ALOGE("failed to open sysfs entry for videodev");
140 continue; /* try next */
143 /* read sysfs entry for device name */
144 size
= (int)fgets(name
, sizeof(name
), stream_fd
);
147 /* check read size */
149 ALOGE("failed to read sysfs entry for videodev");
152 if (strncmp(name
, devname
, strlen(devname
)) == 0) {
153 ALOGI("node found for device %s: /dev/video%d", devname
, minor
);
158 } while (found
== false);
161 snprintf(filename
, sizeof(filename
), "/dev/video%d", minor
);
163 fd
= __v4l2_open(filename
, oflag
, ap
);
167 ALOGI("open video device %s", filename
);
169 ALOGE("failed to open video device %s", filename
);
171 ALOGE("no video device found");
179 int exynos_v4l2_close(int fd
)
186 ALOGE("%s: invalid fd: %d", __func__
, fd
);
195 bool exynos_v4l2_enuminput(int fd
, int index
, char *input_name_buf
)
198 struct v4l2_input input
;
203 ALOGE("%s: invalid fd: %d", __func__
, fd
);
208 ret
= ioctl(fd
, VIDIOC_ENUMINPUT
, &input
, 32);
210 ALOGE("%s: no matching index founds", __func__
);
214 ALOGI("Name of input channel[%d] is %s", input
.index
, input
.name
);
216 strncpy(input_name_buf
, (const char *)input
.name
, 32);
223 int exynos_v4l2_s_input(int fd
, int index
)
226 struct v4l2_input input
;
231 ALOGE("%s: invalid fd: %d", __func__
, fd
);
237 ret
= ioctl(fd
, VIDIOC_S_INPUT
, &input
);
239 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno
, strerror(errno
));
248 bool exynos_v4l2_querycap(int fd
, unsigned int need_caps
)
250 struct v4l2_capability cap
;
256 ALOGE("%s: invalid fd: %d", __func__
, fd
);
260 if (!(need_caps
& V4L2_CAP_VIDEO_CAPTURE
) &&
261 !(need_caps
& V4L2_CAP_VIDEO_CAPTURE_MPLANE
) &&
262 !(need_caps
& V4L2_CAP_VIDEO_OUTPUT
) &&
263 !(need_caps
& V4L2_CAP_VIDEO_OUTPUT_MPLANE
) &&
264 !(need_caps
& V4L2_CAP_VIDEO_OVERLAY
)) {
265 ALOGE("%s: unsupported capabilities", __func__
);
269 memset(&cap
, 0, sizeof(cap
));
271 ret
= ioctl(fd
, VIDIOC_QUERYCAP
, &cap
);
273 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno
, strerror(errno
));
277 if ((need_caps
& cap
.capabilities
) != need_caps
) {
278 ALOGE("%s: unsupported capabilities", __func__
);
287 bool exynos_v4l2_enum_fmt(int fd
, enum v4l2_buf_type type
, unsigned int fmt
)
289 struct v4l2_fmtdesc fmtdesc
;
297 while (ioctl(fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) == 0) {
298 if (fmtdesc
.pixelformat
== fmt
) {
299 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt
, fmtdesc
.index
, fmtdesc
.description
);
308 ALOGE("%s: unsupported pixel format", __func__
);
317 int exynos_v4l2_g_fmt(int fd
, struct v4l2_format
*fmt
)
324 ALOGE("%s: invalid fd: %d", __func__
, fd
);
329 ALOGE("%s: fmt is NULL", __func__
);
333 if (__v4l2_check_buf_type(fmt
->type
) == false) {
334 ALOGE("%s: unsupported buffer type", __func__
);
338 ret
= ioctl(fd
, VIDIOC_G_FMT
, fmt
);
340 ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno
, strerror(errno
));
349 static int __v4l2_s_fmt(int fd
, unsigned int request
, struct v4l2_format
*fmt
)
356 ALOGE("%s: invalid fd: %d", __func__
, fd
);
361 ALOGE("%s: fmt is NULL", __func__
);
365 if (__v4l2_check_buf_type(fmt
->type
) == false) {
366 ALOGE("%s: unsupported buffer type", __func__
);
369 ret
= ioctl(fd
, request
, fmt
);
371 if (request
== VIDIOC_TRY_FMT
)
372 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno
, strerror(errno
));
374 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno
, strerror(errno
));
385 int exynos_v4l2_try_fmt(int fd
, struct v4l2_format
*fmt
)
387 return __v4l2_s_fmt(fd
, VIDIOC_TRY_FMT
, fmt
);
390 int exynos_v4l2_s_fmt(int fd
, struct v4l2_format
*fmt
)
392 return __v4l2_s_fmt(fd
, VIDIOC_S_FMT
, fmt
);
395 int exynos_v4l2_reqbufs(int fd
, struct v4l2_requestbuffers
*req
)
403 ALOGE("%s: invalid fd: %d", __func__
, fd
);
408 ALOGE("%s: req is NULL", __func__
);
412 if ((req
->memory
!= V4L2_MEMORY_MMAP
) &&
413 (req
->memory
!= V4L2_MEMORY_USERPTR
) &&
414 (req
->memory
!= V4L2_MEMORY_DMABUF
)) {
415 ALOGE("%s: unsupported memory type", __func__
);
419 if (__v4l2_check_buf_type(req
->type
) == false) {
420 ALOGE("%s: unsupported buffer type", __func__
);
426 ret
= ioctl(fd
, VIDIOC_REQBUFS
, req
);
428 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret
, strerror(errno
));
432 if (count
!= req
->count
) {
433 ALOGW("number of buffers had been changed: %d => %d", count
, req
->count
);
441 int exynos_v4l2_querybuf(int fd
, struct v4l2_buffer
*buf
)
448 ALOGE("%s: invalid fd: %d", __func__
, fd
);
453 ALOGE("%s: buf is NULL", __func__
);
457 if ((buf
->memory
!= V4L2_MEMORY_MMAP
) &&
458 (buf
->memory
!= V4L2_MEMORY_DMABUF
)) {
459 ALOGE("%s: unsupported memory type", __func__
);
463 if (__v4l2_check_buf_type(buf
->type
) == false) {
464 ALOGE("%s: unsupported buffer type", __func__
);
468 ret
= ioctl(fd
, VIDIOC_QUERYBUF
, buf
);
470 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno
, strerror(errno
));
479 int exynos_v4l2_qbuf(int fd
, struct v4l2_buffer
*buf
)
486 ALOGE("%s: invalid fd: %d", __func__
, fd
);
491 ALOGE("%s: buf is NULL", __func__
);
495 if ((buf
->memory
!= V4L2_MEMORY_MMAP
) &&
496 (buf
->memory
!= V4L2_MEMORY_USERPTR
) &&
497 (buf
->memory
!= V4L2_MEMORY_DMABUF
)) {
498 ALOGE("%s: unsupported memory type", __func__
);
502 if (__v4l2_check_buf_type(buf
->type
) == false) {
503 ALOGE("%s: unsupported buffer type", __func__
);
507 ret
= ioctl(fd
, VIDIOC_QBUF
, buf
);
509 ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno
, strerror(errno
));
518 int exynos_v4l2_dqbuf(int fd
, struct v4l2_buffer
*buf
)
525 ALOGE("%s: invalid fd: %d", __func__
, fd
);
530 ALOGE("%s: buf is NULL", __func__
);
534 if ((buf
->memory
!= V4L2_MEMORY_MMAP
) &&
535 (buf
->memory
!= V4L2_MEMORY_USERPTR
) &&
536 (buf
->memory
!= V4L2_MEMORY_DMABUF
)) {
537 ALOGE("%s: unsupported memory type", __func__
);
541 if (__v4l2_check_buf_type(buf
->type
) == false) {
542 ALOGE("%s: unsupported buffer type", __func__
);
546 ret
= ioctl(fd
, VIDIOC_DQBUF
, buf
);
551 ALOGW("failed to ioctl: VIDIOC_DQBUF (%d - %s)", errno
, strerror(errno
));
560 int exynos_v4l2_streamon(int fd
, enum v4l2_buf_type type
)
567 ALOGE("%s: invalid fd: %d", __func__
, fd
);
571 if (__v4l2_check_buf_type(type
) == false) {
572 ALOGE("%s: unsupported buffer type", __func__
);
576 ret
= ioctl(fd
, VIDIOC_STREAMON
, &type
);
578 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno
, strerror(errno
));
587 int exynos_v4l2_streamoff(int fd
, enum v4l2_buf_type type
)
594 ALOGE("%s: invalid fd: %d", __func__
, fd
);
598 if (__v4l2_check_buf_type(type
) == false) {
599 ALOGE("%s: unsupported buffer type", __func__
);
603 ret
= ioctl(fd
, VIDIOC_STREAMOFF
, &type
);
605 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno
, strerror(errno
));
614 int exynos_v4l2_cropcap(int fd
, struct v4l2_cropcap
*crop
)
621 ALOGE("%s: invalid fd: %d", __func__
, fd
);
626 ALOGE("%s: crop is NULL", __func__
);
630 if (__v4l2_check_buf_type(crop
->type
) == false) {
631 ALOGE("%s: unsupported buffer type", __func__
);
635 ret
= ioctl(fd
, VIDIOC_CROPCAP
, crop
);
637 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno
, strerror(errno
));
646 int exynos_v4l2_g_crop(int fd
, struct v4l2_crop
*crop
)
653 ALOGE("%s: invalid fd: %d", __func__
, fd
);
658 ALOGE("%s: crop is NULL", __func__
);
662 if (__v4l2_check_buf_type(crop
->type
) == false) {
663 ALOGE("%s: unsupported buffer type", __func__
);
667 ret
= ioctl(fd
, VIDIOC_G_CROP
, crop
);
669 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno
, strerror(errno
));
678 int exynos_v4l2_s_crop(int fd
, struct v4l2_crop
*crop
)
685 ALOGE("%s: invalid fd: %d", __func__
, fd
);
690 ALOGE("%s: crop is NULL", __func__
);
694 if (__v4l2_check_buf_type(crop
->type
) == false) {
695 ALOGE("%s: unsupported buffer type", __func__
);
699 ret
= ioctl(fd
, VIDIOC_S_CROP
, crop
);
701 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno
, strerror(errno
));
710 int exynos_v4l2_g_ctrl(int fd
, unsigned int id
, int *value
)
713 struct v4l2_control ctrl
;
720 ALOGE("%s: invalid fd: %d", __func__
, fd
);
724 ret
= ioctl(fd
, VIDIOC_G_CTRL
, &ctrl
);
726 ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d - %s)", errno
, strerror(errno
));
737 int exynos_v4l2_s_ctrl(int fd
, unsigned int id
, int value
)
740 struct v4l2_control ctrl
;
748 ALOGE("%s: invalid fd: %d", __func__
, fd
);
752 ret
= ioctl(fd
, VIDIOC_S_CTRL
, &ctrl
);
754 ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", errno
);
763 int exynos_v4l2_g_parm(int fd
, struct v4l2_streamparm
*streamparm
)
770 ALOGE("%s: invalid fd: %d", __func__
, fd
);
774 if (__v4l2_check_buf_type(streamparm
->type
) == false) {
775 ALOGE("%s: unsupported buffer type", __func__
);
779 ret
= ioctl(fd
, VIDIOC_G_PARM
, streamparm
);
781 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno
, strerror(errno
));
790 int exynos_v4l2_s_parm(int fd
, struct v4l2_streamparm
*streamparm
)
797 ALOGE("%s: invalid fd: %d", __func__
, fd
);
801 if (__v4l2_check_buf_type(streamparm
->type
) == false) {
802 ALOGE("%s: unsupported buffer type", __func__
);
806 ret
= ioctl(fd
, VIDIOC_S_PARM
, streamparm
);
808 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno
, strerror(errno
));
817 int exynos_v4l2_g_ext_ctrl(int fd
, struct v4l2_ext_controls
*ctrl
)
824 ALOGE("%s: invalid fd: %d", __func__
, fd
);
829 ALOGE("%s: ctrl is NULL", __func__
);
833 ret
= ioctl(fd
, VIDIOC_G_EXT_CTRLS
, ctrl
);
835 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno
, strerror(errno
));
842 int exynos_v4l2_s_ext_ctrl(int fd
, struct v4l2_ext_controls
*ctrl
)
849 ALOGE("%s: invalid fd: %d", __func__
, fd
);
854 ALOGE("%s: ctrl is NULL", __func__
);
858 ret
= ioctl(fd
, VIDIOC_S_EXT_CTRLS
, ctrl
);
860 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno
, strerror(errno
));